From: Jerome St-Louis Date: Tue, 31 May 2016 08:55:48 +0000 (-0400) Subject: bindings: Base methods support in Instance class X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?p=sdk;a=commitdiff_plain;h=9ef3c5d258fe045e031ca8dedb5cb6ef8da0a605 bindings: Base methods support in Instance class --- diff --git a/bindings/c/eC.h b/bindings/c/eC.h index 2dabb75..0c55764 100644 --- a/bindings/c/eC.h +++ b/bindings/c/eC.h @@ -98,6 +98,7 @@ extern "C" #define OldArray eC_OldArray #define Window eC_Window +#define DataBox eC_DataBox #define ClassDesignerBase eC_ClassDesignerBase #define DesignerBase eC_DesignerBase @@ -154,36 +155,36 @@ extern "C" // Virtual Method Calls // Base Class -#define _onDisplay(c, i, s, x, y, w, d, a, f) ({ void (* method)(eC_Class *, void *, eC_Surface, int, int, int, void *, Alignment, DataDisplayFlags) = (void (*)(eC_Class *, void *, eC_Surface, int, int, int, void *, Alignment, DataDisplayFlags))((c) ? (c)->_vTbl : class_class->_vTbl)[onDisplay_vTblID]; \ - method ? method((c), i, s, x, y, w, d, a, f) : 1; }) +#define _onDisplay(c, i, s, x, y, w, d, a, f) ({ void (* method)(eC_Class *, void *, eC_Instance /*Surface*/, int, int, int, void *, Alignment, DataDisplayFlags) = (void (*)(eC_Class *, void *, eC_Instance /*eC_Surface*/, int, int, int, void *, Alignment, DataDisplayFlags))((c) ? (c)->_vTbl : class_class->_vTbl)[onDisplay_vTblID]; \ + if(method) method((c), i, s, x, y, w, d, a, f); }) #define _onCompare(c, i, o) ({ int (* method)(eC_Class *, void *, void *) = (int (*)(eC_Class *, void *, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onCompare_vTblID]; \ method ? method((c), i, o) : 1; }) -#define _onCopy(c, i, co, o) ({ void (* method)(eC_Class *, void *, eC_Class *, void *) = (void (*)(eC_Class *, void *, eC_Class *, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onCopy_vTblID]; \ - method ? method((c), i, co, o) : 1; }) +#define _onCopy(c, i, o) ({ void (* method)(eC_Class *, void *, void *) = (void (*)(eC_Class *, void *, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onCopy_vTblID]; \ + if(method) method((c), i, o); }) #define _onFree(c, i) ({ void (* method)(eC_Class *, void *) = (void (*)(eC_Class *, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onFree_vTblID]; \ - method ? method((c), i) : 1; }) + if(method) method((c), i); }) #define _onGetString(c, i, t, d, n) ({ constString (* method)(eC_Class *, void *, char *, void *, bool *) = (constString (*)(eC_Class *, void *, char *, void *, bool *))((c) ? (c)->_vTbl : class_class->_vTbl)[onGetString_vTblID]; \ method ? method((c), i, t, d, n) : null; }) #define _onGetDataFromString(c, i, s) ({ bool (* method)(eC_Class *, void *, constString) = (bool (*)(eC_Class *, void *, constString))((c) ? (c)->_vTbl : class_class->_vTbl)[onGetDataFromString_vTblID]; \ method ? method((c), i, s) : 1; }) -#define _onEdit(c, i, b, o, x, y, w, h, u) ({ eC_Window (* method)(eC_Class *, void *, DataBox, DataBox, int, int, int, int, void *) = (eC_Window (*)(eC_Class *, void *, DataBox, DataBox, int, int, int, int, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onEdit_vTblID]; \ - method ? method((c), i, b, i, x, y, w, h, u) : 1; }) +#define _onEdit(c, i, b, o, x, y, w, h, u) ({ eC_Window (* method)(eC_Class *, void *, eC_DataBox, eC_DataBox, int, int, int, int, void *) = (eC_Window (*)(eC_Class *, void *, eC_DataBox, eC_DataBox, int, int, int, int, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onEdit_vTblID]; \ + method ? method((c), i, b, i, x, y, w, h, u) : null; }) #define _onSerialize(c, i, s) ({ void (* method)(eC_Class *, void *, eC_IOChannel) = (void (*)(eC_Class *, void *, eC_IOChannel))((c) ? (c)->_vTbl : class_class->_vTbl)[onSerialize_vTblID]; \ - method ? method((c), i, s) : 1; }) + if(method) method((c), i, s); }) #define _onUnserialize(c, i, s) ({ void (* method)(eC_Class *, void *, eC_IOChannel) = (void (*)(eC_Class *, void *, eC_IOChannel))((c) ? (c)->_vTbl : class_class->_vTbl)[onUnserialize_vTblID]; \ - method ? method((c), i, s) : 1; }) + if(method) method((c), i, s); }) #define _onSaveEdit(c, i, w, o) ({ bool (* method)(eC_Class *, void *, eC_Window, void *) = (bool (*)(eC_Class *, void *, eC_Window, void *))((c) ? (c)->_vTbl : class_class->_vTbl)[onSaveEdit_vTblID]; \ method ? method((c), i, w, o) : 1; }) // Base Virtual Methods for Normal Classes -#define Instance_onDisplay(c, i, s, x, y, w, d, a, f) _onDisplay(i ? i->_class : c, i, s, x, y, w, d, a, f) -#define Instance_onCompare(c, i, o) _onCompare(i ? i->_class : c, i, o) -#define Instance_onCopy(c, i, co, o) _onCopy(c, &i, co, o) -#define Instance_onFree(c, i) _onFree(i ? i->_class : c, i) -#define Instance_onGetString(c, i, t, d, n) _onGetString(i ? i->_class : c, i, t, d, n) +#define Instance_onDisplay(c, i, s, x, y, w, d, a, f) _onDisplay((i) ? (i)->_class : c, i, s, x, y, w, d, a, f) +#define Instance_onCompare(c, i, o) _onCompare((i) ? (i)->_class : c, i, o) +#define Instance_onCopy(c, i, o) _onCopy((o) ? (o)->_class : c, &i, o) +#define Instance_onFree(c, i) _onFree((i) ? (i)->_class : c, i) +#define Instance_onGetString(c, i, t, d, n) _onGetString((i) ? (i)->_class : c, i, t, d, n) #define Instance_onGetDataFromString(c, i, s) _onGetDataFromString(c, &i, s) -#define Instance_onEdit(c, i, b, o, x, y, w, h, u) _onEdit(i ? i->_class : c, i, b, o, x, y, w, h, u) -#define Instance_onSerialize(c, i, s) _onSerialize(i ? i->_class : c, i, s) +#define Instance_onEdit(c, i, b, o, x, y, w, h, u) _onEdit((i) ? (i)->_class : c, i, b, o, x, y, w, h, u) +#define Instance_onSerialize(c, i, s) _onSerialize((i) ? (i)->_class : c, i, s) #define Instance_onUnserialize(c, i, s) _onUnserialize(c, &i, s) #define Instance_onSaveEdit(c, i, w, o) _onSaveEdit(c, &i, w, o) @@ -827,7 +828,7 @@ struct class_members_Instance Class * _class; int _refCount; }; -struct layout_Module +struct class_members_Module { Application application; OldList classes; @@ -1095,6 +1096,7 @@ Module eC_init(bool guiApp, int argc, char * argv[]); #undef OldArray #undef Window + #undef DataBox #undef ClassDesignerBase #undef DesignerBase diff --git a/bindings/c/ecere.h b/bindings/c/ecere.h index b6399a2..6de16e0 100644 --- a/bindings/c/ecere.h +++ b/bindings/c/ecere.h @@ -37,6 +37,7 @@ extern "C" #define FontResource eC_FontResource #define Window eC_Window +#define DataBox eC_DataBox #define Button eC_Button #define Label eC_Label #define MessageBox eC_MessageBox @@ -288,6 +289,9 @@ extern int Button_notifyClicked_vTblID; extern Class * class_ToolButton; +///////////// DataBox Class ///////////////////////////////////////////////// +typedef Window DataBox; + ///////////// GuiApplication Class ///////////////////////////////////////////////// extern Class * class_GuiApplication; @@ -300,6 +304,7 @@ Module ecere_init(Module fromModule); #undef MessageBox #undef Label #undef Window + #undef DataBox #undef GuiApplication #undef FontResource diff --git a/bindings/c/samples/form.c b/bindings/c/samples/form.c index 849246f..e46488b 100644 --- a/bindings/c/samples/form.c +++ b/bindings/c/samples/form.c @@ -20,7 +20,7 @@ static bool HelloForm2_button_notifyClicked(HelloForm2 this, Button button, int MessageBox msgBox = newi(class_MessageBox); double i = 3.14159265; char tmp[256]; - constString s = onGetString(class_double, &i, tmp, null, null); + constString s = _onGetString(class_double, &i, tmp, null, null); PrintLn(class_String, "Hello! -- ", class_String, s, null); // Need to terminate with a null! Window_set_caption(msgBox, $("Hello!")); diff --git a/bindings/cpp/eC.cpp b/bindings/cpp/eC.cpp index 59e9c07..41806dd 100644 --- a/bindings/cpp/eC.cpp +++ b/bindings/cpp/eC.cpp @@ -3,6 +3,7 @@ TCPPClass Instance::_class; TCPPClass Module::_class; TCPPClass Application::_class; +TCPPClass IOChannel::_class; void eC_cpp_init(Module & module) { diff --git a/bindings/cpp/eC.hpp b/bindings/cpp/eC.hpp index edfd5ca..0ecc078 100644 --- a/bindings/cpp/eC.hpp +++ b/bindings/cpp/eC.hpp @@ -14,7 +14,7 @@ #define INSTANCEL(x, c) (*(void **)((char *)(x) + (c)->offset)) #define _INSTANCE(x, c) INSTANCEL((x) ? (x) : 0, c) -#define INSTANCE(x, c) ({c * _i = (c *)_INSTANCE(x, x->_class); _i ? *_i : c { x }; }) +#define INSTANCE(x, c) ({c * _i = (c *)_INSTANCE(x, x->_class); _i ? *_i : c(x); }) #define newt(t, c) eC_new(class_ ## t->structSize * c) @@ -33,6 +33,7 @@ #define REGISTER_CPP_CLASS(n, a) n::_class.setup(_REGISTER_CLASS(n, "CPP" #n, #n, a)); #define _CONSTRUCT(c, b) \ + INSTANCE_VIRTUAL_METHODS(c) \ static TCPPClass _class; \ static eC_bool constructor(eC_Instance i) { if(!Class_isDerived(i->_class, _class.impl)) return new c(i) != null; return true;} \ static void destructor(eC_Instance i) { c * inst = (c *)_INSTANCE(i, _class.impl); if(_class.destructor) ((void (*)(c & self))_class.destructor)(*inst); delete inst; } \ @@ -69,12 +70,14 @@ #define SELF(c, n) c * self = ((c *)(((char *)this) - (char *)&((c *)0)->n)) -#define VIRTUAL_METHOD(n, c, b, r, p, sp, d) \ +#define _ARG , + +#define VIRTUAL_METHOD(n, c, b, r, p0, ep, p, d) \ struct c ## _ ## n ## _Functor \ { \ int _[0]; \ - typedef r (* FunctionType)p; \ - FunctionType operator= (FunctionType func) \ + typedef r (* FunctionType)(p0 p); \ + inline FunctionType operator= (FunctionType func) \ { \ SELF(c, n); \ if(self->vTbl == c::_class.vTbl) \ @@ -86,38 +89,53 @@ ((FunctionType *)self->vTbl)[b ## _ ## n ## _vTblID] = func; \ return func; \ } \ - r operator()sp \ + inline r operator()(ep p) \ { \ + \ SELF(c, n); \ d; \ } \ } n; \ - static void register_ ## n(CPPClass & cl, c ## _ ## n ## _Functor::FunctionType func) \ + inline static void register_ ## n(CPPClass & cl, c ## _ ## n ## _Functor::FunctionType func) \ { \ ((c ## _ ## n ## _Functor::FunctionType *)cl.vTbl)[b ## _ ## n ## _vTblID] = func; \ } -#define REGISTER_METHOD(ns, n, bc, c, r, p, o, a, ea, rv) \ +#define _REGISTER_METHOD(cp1, cp2, ns, n, bc, c, r, p, ocl, oi, code, ea, rv) \ addMethod(_class.impl, ns, (void *) +[]p \ { \ - Class * cl = (Class *)o->_class; \ - c * i = (c *)_INSTANCE(o, cl); \ - if(i) \ + Class * cl = (ocl) ? (Class *)(ocl)->_class : null; \ + cp1 \ + c * i = (oi) ? (c *)_INSTANCE(oi, cl) : null; \ + int vid = bc ## _ ## n ## _vTblID; \ + bc ## _ ## n ## _Functor::FunctionType fn; \ + if(i && i->vTbl && i->vTbl[vid]) \ { \ - int vid = bc ## _ ## n ## _vTblID; \ - if(i->vTbl && i->vTbl[vid]) \ - { \ - return ((bc ## _ ## n ## _Functor::FunctionType)i->vTbl[vid]) a; \ - } \ - else \ - { \ - auto method = ((r (*) p)(class_ ## c->_vTbl)[bc ## _ ## n ## _vTblID]); \ - if(method) return method ea; \ - } \ + fn = (bc ## _ ## n ## _Functor::FunctionType) i->vTbl[vid]; \ + code; \ + } \ + cp2 \ + else \ + { \ + auto method = ((r (*) p)(class_ ## c->_vTbl)[bc ## _ ## n ## _vTblID]); \ + if(method) return method ea; \ + return rv; \ } \ - return rv; \ }) +#define REGISTER_METHOD(ns, n, bc, c, r, p, ocl, oi, code, ea, rv) \ + _REGISTER_METHOD(,, ns, n, bc, c, r, p, ocl, oi, code, ea, rv) + +#define REGISTER_TYPED_METHOD(ns, n, bc, c, r, p, ocl, oi, code, ea, rv) \ + _REGISTER_METHOD(\ + CPPClass * cppcl = _class ? (CPPClass *)_class->data : null;, \ + else if(cppcl && cppcl->vTbl && cppcl->vTbl[vid]) \ + { \ + fn = (bc ## _ ## n ## _Functor::FunctionType) cppcl->vTbl[vid]; \ + code; \ + }, \ + ns, n, bc, c, r, p, ocl, oi, code, ea, rv) + #define property(n, sg) struct n ## Prop { n ## Prop() { }; int _[0]; sg } n; #define _set(t, n, d) \ @@ -150,6 +168,13 @@ public: typedef void (* Function)(void); Class * impl; Function * vTbl; + inline CPPClass() { }; + inline CPPClass(const CPPClass & c) = delete; + inline CPPClass(const CPPClass && c) + { + impl = c.impl; + vTbl = c.vTbl; + } }; template @@ -195,26 +220,75 @@ public: #define Instance_onSaveEdit_vTblID onSaveEdit_vTblID // Normal Class Definitions -#define Instance_class_registration(d) \ - REGISTER_METHOD("OnCompare", onCompare, Instance, d, bool, (eC_Class * c, eC_Instance o, eC_Instance o2), \ - o, (c, *i, *(Instance *)INSTANCEL(o2, o2->_class)), (c, o, o2), true); -/* - REGISTER_METHOD("OnDisplay", onDisplay, Instance, d, void, (eC_Class * c, eC_Instance o, eC_Instance s, int x, int y, int w, void * f, Alignment a, DataDisplayFlags df), \ - o, (c, *i, Surface(s), x, y, w, f, a, df), (c, o, s, x, y, w, f, a, df), ); -*/ +#define Instance_class_registration(d) \ + REGISTER_TYPED_METHOD("OnCompare", onCompare, Instance, d, int, (Class * _class, eC_Instance o, eC_Instance o2), \ + o, o, return fn(*i, *(Instance *)INSTANCEL(o2, o2->_class)), (_class, o, o2), 1); \ + REGISTER_TYPED_METHOD("OnDisplay", onDisplay, Instance, d, void, (Class * _class, eC_Instance o, eC_Instance /*eC_Surface */ s, int x, int y, int w, void * f, Alignment a, DataDisplayFlags df), \ + o, o, Surface surface(s); fn(*i, surface, x, y, w, f, a, df), (_class, o, s, x, y, w, f, a, df), ); \ + REGISTER_TYPED_METHOD("OnCopy", onCopy, Instance, d, void, (Class * _class, eC_Instance * dest, eC_Instance src), \ + src, dest ? *dest : null, fn(*i, *(Instance *)INSTANCEL(src, src->_class) ), (_class, dest, src), ); \ + REGISTER_TYPED_METHOD("OnFree", onFree, Instance, d, void, (Class * _class, eC_Instance o), \ + o, o, fn(*i), (_class, o), ); \ + REGISTER_TYPED_METHOD("OnGetString", onGetString, Instance, d, constString, (Class * _class, eC_Instance o, String tempString, void * fieldData, eC_bool * needClass), \ + o, o, bool nc; constString r = fn(*i, tempString, fieldData, needClass ? &nc : null); if(needClass) *needClass = nc; return r;, (_class, o, tempString, fieldData, needClass), (constString)null); \ + REGISTER_TYPED_METHOD("OnGetDataFromString", onGetDataFromString, Instance, d, bool, (Class * _class, eC_Instance * o, constString string), \ + o ? *o : null, o ? *o : null, return fn(*i, string); , (_class, o, string), false); \ + REGISTER_TYPED_METHOD("OnSerialize", onSerialize, Instance, d, void, (Class * _class, eC_Instance o, eC_Instance /*eC_IOChannel*/ c), \ + o, o, IOChannel * ref = (IOChannel *)_INSTANCE(c, c->_class); if(ref) fn(*i, *ref); else { IOChannel channel(c); fn(*i, channel); }, (_class, o, c), ); \ + REGISTER_TYPED_METHOD("OnUnserialize", onUnserialize, Instance, d, void, (Class * _class, eC_Instance * o, eC_Instance /*eC_IOChannel*/ c), \ + o ? *o : null, o, IOChannel * ref = (IOChannel *)_INSTANCE(c, c->_class); if(ref) fn(*i, *ref); else { IOChannel channel(c); fn(*i, channel); }, (_class, o, c), ); \ + REGISTER_TYPED_METHOD("OnSaveEdit", onSaveEdit, Instance, d, bool, (Class * _class, eC_Instance * o, eC_Instance /*eC_Window*/ w, void * object), \ + o ? *o : null, o, Window * ref = (Window *)_INSTANCE(w, w->_class); if(ref) return fn(*i, *ref, object); else { Window window(w); return fn(*i, window, object); }, (_class, o, w, object), false); \ + REGISTER_TYPED_METHOD("OnEdit", onEdit, Instance, d, eC_Window, (Class * _class, eC_Instance o, eC_Instance /*eC_DataBox */db, void * obsolete, int x, int y, int w, int h, void * userData), \ + o, o, \ + Window /*DataBox*/ * ref = (Window /*DataBox*/ *)_INSTANCE(db, db->_class); \ + Window * ret; \ + if(ref) ret = &fn(*i, *ref, obsolete, x, y, w, h, userData); \ + else { Window /*DataBox */dataBox(db); \ + ret = &fn(*i, dataBox, obsolete, x, y, w, h, userData); } \ + return ret ? ret->impl : null;, \ + (_class, o, db, obsolete, x, y, w, h, userData), (eC_Window)null); + +#define INSTANCE_VIRTUAL_METHODS(c) \ + VIRTUAL_METHOD(onCompare, c, Instance, \ + int, c & _ARG, , c & b, \ + return Instance_onCompare(_class.impl, self ? self->impl : (eC_Instance)null, &b ? b.impl : (eC_Instance)null)); \ + VIRTUAL_METHOD(onCopy, c, Instance, \ + void, c & _ARG, , c & src, \ + return Instance_onCopy(_class.impl, self->impl, &src ? src.impl : (eC_Instance)null)); \ + VIRTUAL_METHOD(onDisplay, c, Instance, \ + void, c & _ARG, , Surface & surface _ARG int x _ARG int y _ARG int w _ARG void * fieldData _ARG Alignment alignment _ARG DataDisplayFlags flags, \ + Instance_onDisplay(_class.impl, self ? self->impl : (eC_Instance)null, &surface ? ((Instance *)&surface)->impl : (eC_Instance)null, x, y, w, fieldData, alignment, flags)); \ + VIRTUAL_METHOD(onFree, c, Instance, \ + void, c &, , , \ + return Instance_onFree(_class.impl, self->impl)); \ + VIRTUAL_METHOD(onGetString, c, Instance, \ + constString, c & _ARG, , String tempString _ARG void * fieldData _ARG bool * needClass, \ + return Instance_onGetString(_class.impl, self ? self->impl : (eC_Instance)null, tempString, fieldData, needClass)); \ + VIRTUAL_METHOD(onGetDataFromString, c, Instance, \ + bool, c & _ARG, , constString string, \ + return Instance_onGetDataFromString(_class.impl, self->impl, string)); \ + VIRTUAL_METHOD(onSerialize, c, Instance, \ + void, c & _ARG, , IOChannel & channel, \ + return Instance_onSerialize(_class.impl, self ? self->impl : (eC_Instance)null, &channel ? ((Instance *)&channel)->impl : (eC_Instance)null)); \ + VIRTUAL_METHOD(onUnserialize, c, Instance, \ + void, c & _ARG, , IOChannel & channel, \ + return Instance_onUnserialize(_class.impl, self->impl, &channel ? ((Instance *)&channel)->impl : (eC_Instance)null)); \ + VIRTUAL_METHOD(onSaveEdit, c, Instance, \ + bool, c & _ARG, , Window & window _ARG void * object, \ + return Instance_onSaveEdit(_class.impl, self->impl, &window ? ((Instance *)&window)->impl : (eC_Instance)null, object)); \ + VIRTUAL_METHOD(onEdit, c, Instance, \ + Window &, c & _ARG, , Window /*DataBox*/ & dataBox _ARG void * obsolete _ARG int x _ARG int y _ARG int w _ARG int h _ARG void * userData, \ + eC_Window window = Instance_onEdit(_class.impl, self->impl, &dataBox ? ((Instance *)&dataBox)->impl : (eC_Instance)null, obsolete, x, y, w, h, userData); \ + return *(Window *)_INSTANCE(window, window->_class); ); -/* -#define Instance_onCopy(c, i, co, o) onCopy(c, &i, co, o) -#define Instance_onFree(c, i) onFree(i ? i->_class : c, i) -#define Instance_onGetString(c, i, t, d, n) onGetString(i ? i->_class : c, i, t, d, n) -#define Instance_onGetDataFromString(c, i, s) onGetDataFromString(c, &i, s) -#define Instance_onEdit(c, i, b, o, x, y, w, h, u) onEdit(i ? i->_class : c, i, b, o, x, y, w, h, u) -#define Instance_onSerialize(c, i, s) onSerialize(i ? i->_class : c, i, s) -#define Instance_onUnserialize(c, i, s) onUnserialize(c, &i, s) -#define Instance_onSaveEdit(c, i, w, o) onSaveEdit(c, &i, w, o) -*/ class Surface; +class IOChannel; +class Window; +class DataBox; + +typedef eC_Window eC_DataBox; typedef uint32 Alignment; typedef uint32 DataDisplayFlags; @@ -228,18 +302,10 @@ public: static eC_bool constructor(eC_Instance i) { if(!Class_isDerived(i->_class, _class.impl)) return new Instance(i) != null; return true; } static void destructor(eC_Instance i) { Instance * inst = (Instance *)_INSTANCE(i, _class.impl); delete inst; } - static void class_registration(CPPClass & _class) { Instance_class_registration(Instance); } -/* - VIRTUAL_METHOD(onDisplay, Instance, Instance, - void, (eC_Class *, Instance &, Surface &, int, int, int, void *, Alignment, DataDisplayFlags), - (eC_Class * cl, Instance & foo, Surface & surface, int x, int y, int w, void * fieldData, Alignment alignment, DataDisplayFlags flags), - Instance_onDisplay(cl, foo.impl, surface.impl, x, y, w, fieldData, alignment, flags)); -*/ + static void class_registration(CPPClass & _class); + //static void class_registration(CPPClass & _class) { Instance_class_registration(Instance); } - VIRTUAL_METHOD(onCompare, Instance, Instance, - bool, (eC_Class *, Instance &, Instance &), - (eC_Class * cl, Instance & a, Instance & b), - return Instance_onCompare(cl, self->impl, b.impl)); + INSTANCE_VIRTUAL_METHODS(Instance); inline explicit Instance(eC_Instance _impl, CPPClass & cl = _class) { @@ -262,14 +328,17 @@ public: { if(impl && impl->_class) { - Instance ** i = (Instance **)&INSTANCEL(impl, impl->_class); - if(i && *i == this) - *i = null; - if(vTbl) + if(impl->_class->data) { - CPPClass * cl = (CPPClass *)impl->_class->data; - if(cl && vTbl != cl->vTbl) - delete [] vTbl; + Instance ** i = (Instance **)&INSTANCEL(impl, impl->_class); + if(i && *i == this) + *i = null; + if(vTbl) + { + CPPClass * cl = (CPPClass *)impl->_class->data; + if(cl && vTbl != cl->vTbl) + delete [] vTbl; + } } Instance_decref(impl); } @@ -293,7 +362,7 @@ void eC_cpp_init(Module & module); void ecere_cpp_init(Module & module); #define Application_class_registration(d) \ - REGISTER_METHOD("Main", main, Application, d, void, (eC_Instance o), o, (*i), (o), ); + REGISTER_METHOD("Main", main, Application, d, void, (eC_Instance o), o, o, return fn(*i), (o), ); class Application : public Module { @@ -318,7 +387,7 @@ public: #define PSELF SELF(Application, exitCode) property(exitCode, get(int, exitCode, return self ? _IPTR(self->impl, class_Application, class_members_Application)->exitCode : 0) ); - VIRTUAL_METHOD(main, Application, Application, void, (Application &), (), + VIRTUAL_METHOD(main, Application, Application, void, Application &, , , return Application_main(self->impl)); }; @@ -354,55 +423,55 @@ public: // 2. This shound end up calling static class virtual table if overriden // 3. Registering a method (e.g. onRedraw) needs to call addMethod to update the virtual table, with C callback -class Array : Container +class Array : public Container { public: CONSTRUCT(Array, Container) { } }; -class CustomAVLTree : Container +class CustomAVLTree : public Container { public: CONSTRUCT(CustomAVLTree, Container) { } }; -class AVLTree : CustomAVLTree +class AVLTree : public CustomAVLTree { public: CONSTRUCT(AVLTree, CustomAVLTree) { } }; -class Map : CustomAVLTree +class Map : public CustomAVLTree { public: CONSTRUCT(Map, CustomAVLTree) { } }; -class LinkList : Container +class LinkList : public Container { public: CONSTRUCT(LinkList, Container) { } }; -class List : LinkList +class List : public LinkList { public: CONSTRUCT(List, LinkList) { } }; -class IOChannel : Instance +class IOChannel : public Instance { public: CONSTRUCT(IOChannel, Instance) { } }; -class SerialBuffer : IOChannel +class SerialBuffer : public IOChannel { public: CONSTRUCT(SerialBuffer, IOChannel) { } }; -class OldArray : Instance +class OldArray : public Instance { public: CONSTRUCT(OldArray, Instance) { } @@ -410,12 +479,12 @@ public: // How to handle inheritance from classes not loaded yet? /* -class ClassDesignerBase : Window +class ClassDesignerBase : public Window { public: CONSTRUCT(ClassDesignerBase, Window) { } }; -class DesignerBase : Window +class DesignerBase : public Window { public: CONSTRUCT(DesignerBase, Window) { } diff --git a/bindings/cpp/ecere.cpp b/bindings/cpp/ecere.cpp index 92d074d..1d786d6 100644 --- a/bindings/cpp/ecere.cpp +++ b/bindings/cpp/ecere.cpp @@ -21,3 +21,7 @@ void ecere_cpp_init(Module & module) REGISTER_CPP_CLASS(MessageBox, module); } } + +// Instance methods depending on libecere +void Instance::class_registration(CPPClass & _class) { Instance_class_registration(Instance); } +void FontResource::class_registration(CPPClass & _class) { Instance_class_registration(FontResource); } diff --git a/bindings/cpp/ecere.hpp b/bindings/cpp/ecere.hpp index 8a0405a..583aaf2 100644 --- a/bindings/cpp/ecere.hpp +++ b/bindings/cpp/ecere.hpp @@ -30,6 +30,8 @@ class FontResource : public Instance public: CONSTRUCT(FontResource, Instance) { } + REGISTER(); // { Instance_class_registration(FontResource); } + inline FontResource(constString faceName, float size = 10, eC_bool bold = false, eC_bool italic = false) : FontResource() { this->faceName = faceName; @@ -64,10 +66,8 @@ public: ****************************************************************************/ ///////////// Window Class ///////////////////////////////////////////////// #define Window_class_registration(d) \ - REGISTER_METHOD("OnRedraw", onRedraw, Window, d, void, (eC_Window o, eC_Surface s), o, (*i, Surface { s }), (o, s), ); \ - REGISTER_METHOD("OnCreate", onCreate, Window, d, bool, (eC_Window o), o, (*i), (o), true); - -bool foo(eC_Instance o); + REGISTER_METHOD("OnRedraw", onRedraw, Window, d, void, (eC_Window o, eC_Surface s), o, o, Surface surface(s); return fn(*i, surface), (o, s), ); \ + REGISTER_METHOD("OnCreate", onCreate, Window, d, bool, (eC_Window o), o, o, return fn(*i), (o), true); class Window : public Instance { @@ -76,9 +76,9 @@ public: REGISTER() { Window_class_registration(Window); } - VIRTUAL_METHOD(onCreate, Window, Window, bool, (Window &), (), + VIRTUAL_METHOD(onCreate, Window, Window, bool, Window &, , , return Window_onCreate(self->impl)); - VIRTUAL_METHOD(onRedraw, Window, Window, void, (Window &, Surface), (Surface surface), + VIRTUAL_METHOD(onRedraw, Window, Window, void, Window & _ARG, , Surface & surface, return Window_onRedraw(self->impl, surface.impl)); DialogResult modal() { return Window_modal(impl); } @@ -190,7 +190,7 @@ public: Window_class_registration(d); \ REGISTER_METHOD("NotifyClicked", notifyClicked, Button, d, \ bool, (eC_Window m, eC_Button b, int x, int y, Modifiers mods), \ - b, (*(Window *)INSTANCEL(m, m->_class), *(Button *)INSTANCEL(b, b->_class), x, y, mods), \ + b, b, return fn(*(Window *)INSTANCEL(m, m->_class), *(Button *)INSTANCEL(b, b->_class), x, y, mods), \ (m, b, x, y, mods), true); class Button : public Window @@ -200,7 +200,7 @@ public: REGISTER() { Button_class_registration(Button); } - VIRTUAL_METHOD(notifyClicked, Button, Button, bool, (Window &, Button &, int, int, Modifiers), (Window & window, Button & button, int x, int y, Modifiers mods), + VIRTUAL_METHOD(notifyClicked, Button, Button, bool, Window & _ARG, Window & window _ARG, Button & button _ARG int x _ARG int y _ARG Modifiers mods, return Button_notifyClicked(self->impl, window.impl, button.impl, x, y, mods)); }; diff --git a/bindings/cpp/samples/form.cpp b/bindings/cpp/samples/form.cpp index f4bfb76..d2be761 100644 --- a/bindings/cpp/samples/form.cpp +++ b/bindings/cpp/samples/form.cpp @@ -8,6 +8,46 @@ GuiApplication app; MAIN_DEFINITION; +class Foo : public Instance +{ +public: + int a, b; + Foo(int a, int b) : Foo() { this->a = a, this->b = b; }; + + CONSTRUCT(Foo, Instance) + { + onCopy = [](Foo & self, Foo & other) + { + printf("%d, %d\n", other.a, other.b); + printf("self: %p\n", &self); + self.a = other.a; + self.b = other.b; + }; + + onCompare = [](Foo & self, Foo & other) + { + if(self.a > other.a) return 1; + if(self.a < other.a) return -1; + if(self.b > other.b) return 1; + if(self.b < other.b) return -1; + return 0; + }; + + /*onDisplay = [](Foo & self, Surface & s, int x , int y , int w, void * fd, Alignment a, DataDisplayFlags f) + { + printf("Meh\n"); + }; + */ + } + + REGISTER() + { + //Instance::class_registration(_class); + register_onDisplay(_class, [](Foo & _self, Surface & s, int x , int y , int w, void * fd, Alignment a, DataDisplayFlags f) { printf("Meh\n"); }); + } +}; +REGISTER_CLASS_DEF(Foo, Instance, app); + class HelloForm2 : public Window { public: @@ -27,39 +67,62 @@ public: button.parent = this; button.position = { 200, 200 }; button.caption = $("Yay!!"); - // button.onRedraw = [](Window & foo, Surface s){ }; + // button.onRedraw = [](Window & w, Surface s){ }; button.notifyClicked = [](Window & owner, Button & btn, int x, int y, Modifiers mods) { double i = 3.14159265; char tmp[256]; constString s = _onGetString(class_double, &i, tmp, null, null); - PrintLn(class_String, "Hello! -- ", class_String, s, null); // Need to terminate with a null! - HelloForm2 & self = (HelloForm2 &)owner; - MessageBox($("C++ Bindings!"), self.button.caption).modal(); + //PrintLn(class_String, "Hello! -- ", class_String, s, null); // Need to terminate with a null! + //HelloForm2 & self = (HelloForm2 &)owner; + //MessageBox($("C++ Bindings!"), self.button.caption).modal(); - FontResource a("Arial", 20, true); + /*FontResource a("Arial", 20, true); FontResource b("Comic Sans MS", 20, true); FontResource c("Arial", 20, true); - bool ab = a.onCompare(class_FontResource, a, b); - bool ac = a.onCompare(class_FontResource, a, c); + int ab = ((FontResource *)null)->onCompare(b); + //bool ab = ((FontResource *)null)->onCompare(*(FontResource *)null); + //bool ac = a.onCompare(c); + int ac = a.onCompare(*(FontResource *)null); printf("a compare b = %d\n", ab); - printf("a compare c = %d\n", ac); - + printf("a compare c = %d\n", ac);*/ + + { + Foo obj1 { 2, 3 }; + Foo obj2 { 2, 4 }; + Foo obj3 { 2, 3 }; + /*Foo obj4; obj4.onCopy(obj1); + FontResource fr; + fr.onCopy(a); + printf("result: face = %s, size = %f, bold = %d\n", + (constString)fr.faceName, (float)fr.size, (int)fr.bold); + printf("after"); + */ + Surface s { }; + ((Foo *)null)->onDisplay(s, 0,0,0, null, 0, 0); + //((Foo *)&obj3)->onDisplay(Surface { }, 0,0,0, null, 0, 0); + + int r; + r = obj1.onCompare(obj2); printf("result: %d\n", r); + //r = obj2.onCompare(obj1); printf("result: %d\n", r); + //r = obj1.onCompare(obj3); printf("result: %d\n", r); + //printf("result: a = %d, b = %d\n", obj4.a, obj4.b); + } return true; }; - onCreate = [](Window & w) + /*onCreate = [](Window & w) { MessageBox($("Cool"), $("Creation!")).modal(); return true; - }; + };*/ //onRedraw(Surface()); //onCreate(); } - /*static void myOnRedraw(Window & w, Surface surface) + /*static void myOnRedraw(Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Testing stuff!")); //surface.writeTextf(100, 100, "%d + %d = %d", 2, 3, 2+3); @@ -68,7 +131,7 @@ public: REGISTER() { Window::class_registration(_class); - register_onRedraw(_class, [](Window & w, Surface surface) + register_onRedraw(_class, [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Class Method!")); //surface.writeTextf(100, 100, "%d + %d = %d", 2, 3, 2+3); @@ -84,8 +147,9 @@ public: { background = 0x50B0F0; position = { 0, 0 }; + font = { "Monaco", 30, true }; - onRedraw = [](Window & w, Surface surface) + onRedraw = [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Instance Method!")); //surface.writeTextf(100, 100, "%d + %d = %d", 2, 3, 2+3); @@ -95,4 +159,4 @@ public: REGISTER_CLASS_DEF(HelloForm3, HelloForm2, app); HelloForm2 hello2; -HelloForm3 hello3; +//HelloForm3 hello3; diff --git a/bindings/cpp/samples/sample1.cpp b/bindings/cpp/samples/sample1.cpp index 832f6ee..1dbccc8 100644 --- a/bindings/cpp/samples/sample1.cpp +++ b/bindings/cpp/samples/sample1.cpp @@ -36,7 +36,7 @@ public: { Window::class_registration(_class); - register_onRedraw(_class, [](Window & w, Surface surface) { surface.writeTextf(100, 100, $("Class Method!")); }); + register_onRedraw(_class, [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Class Method!")); }); DESTRUCT(HelloForm) = [](HelloForm & self) { printf("It's the end my friend!\n"); }; } diff --git a/bindings/cpp/samples/sample2.cpp b/bindings/cpp/samples/sample2.cpp index a9b89eb..a85eb4a 100644 --- a/bindings/cpp/samples/sample2.cpp +++ b/bindings/cpp/samples/sample2.cpp @@ -34,7 +34,7 @@ public: REGISTER() { - register_onRedraw(_class, [](Window & w, Surface surface) { surface.writeTextf(100, 100, $("Class Method!")); }); + register_onRedraw(_class, [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Class Method!")); }); } }; diff --git a/bindings/cpp/samples/sample3.cpp b/bindings/cpp/samples/sample3.cpp index 297475e..896c6e0 100644 --- a/bindings/cpp/samples/sample3.cpp +++ b/bindings/cpp/samples/sample3.cpp @@ -35,7 +35,7 @@ public: REGISTER() { Window::class_registration(_class); - register_onRedraw(_class, [](Window & w, Surface surface) { surface.writeTextf(100, 100, $("Class Method!")); }); + register_onRedraw(_class, [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Class Method!")); }); } }; diff --git a/bindings/cpp/samples/sample4.cpp b/bindings/cpp/samples/sample4.cpp index 08f8f75..cd5993e 100644 --- a/bindings/cpp/samples/sample4.cpp +++ b/bindings/cpp/samples/sample4.cpp @@ -31,7 +31,7 @@ public: return true; }; - onRedraw = [](Window & w, Surface surface) { surface.writeTextf(100, 100, $("Instance Method!")); }; + onRedraw = [](Window & w, Surface & surface) { surface.writeTextf(100, 100, $("Instance Method!")); }; } }; GuiApplication app;