Index: TODO =================================================================== diff -u -r0e33ba821d29af5a646fd29c2722baedddcc25b8 -r13d14668e746b4f8c6461288cdd29673db4604dd --- TODO (.../TODO) (revision 0e33ba821d29af5a646fd29c2722baedddcc25b8) +++ TODO (.../TODO) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -2496,6 +2496,11 @@ * added a configure flag for "class" * removed method "class" (should be used via "/obj/ configure -class ...") * removed method residualargs from nx + + * added C-implemented method "init" for orthogonality + * allow specification of system method handles in nsf::createobjectsystem + * automatically register alias, when system-method handle + was provided and a same-named method is defined TODO: Index: generic/gentclAPI.decls =================================================================== diff -u -r65f8883a4596ea98365b7de1652700e3ac7394cc -r13d14668e746b4f8c6461288cdd29673db4604dd --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 65f8883a4596ea98365b7de1652700e3ac7394cc) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -187,6 +187,10 @@ {-argName "guard" -required 1 -type tclobj} } +objectMethod init NsfOInitMethod { + {-argName "args" -type allargs} +} + objectMethod instvar NsfOInstvarMethod { {-argName "args" -type allargs} } Index: generic/nsf.c =================================================================== diff -u -r041c4ff0c72631375bd6afffc58ef8dc40d9555c -r13d14668e746b4f8c6461288cdd29673db4604dd --- generic/nsf.c (.../nsf.c) (revision 041c4ff0c72631375bd6afffc58ef8dc40d9555c) +++ generic/nsf.c (.../nsf.c) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -262,6 +262,8 @@ static Tcl_Obj *AliasGet(Tcl_Interp *interp, Tcl_Obj *cmdName, CONST char *methodName, int withPer_object, int leaveError); static int AliasDeleteObjectReference(Tcl_Interp *interp, Tcl_Command cmd); +static int NsfAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, + CONST char *methodName, int withFrame, Tcl_Obj *cmdName); /* prototypes for (class) list handling */ static NsfClasses ** NsfClassListAdd(NsfClasses **firstPtrPtr, NsfClass *cl, ClientData clientData); @@ -2105,13 +2107,8 @@ int i; for (i=0; i<=NSF_o_unknown_idx; i++) { - Tcl_Obj *methodObj = osPtr->methods[i]; - /*fprintf(stderr, "ObjectSystemFree [%d] %p ", i, methodObj);*/ - if (methodObj) { - /*fprintf(stderr, "%s refCount %d", ObjStr(methodObj), methodObj->refCount);*/ - DECR_REF_COUNT(methodObj); - } - /*fprintf(stderr, "\n");*/ + if (osPtr->methods[i]) { DECR_REF_COUNT(osPtr->methods[i]); } + if (osPtr->handles[i]) { DECR_REF_COUNT(osPtr->handles[i]); } } if (osPtr->rootMetaClass && osPtr->rootClass) { @@ -2171,15 +2168,18 @@ for (osPtr = RUNTIME_STATE(interp)->objectSystems; osPtr; osPtr = osPtr->nextPtr) { for (i=0; i<=NSF_o_unknown_idx; i++) { Tcl_Obj *methodObj = osPtr->methods[i]; + if (methodObj && !strcmp(methodName, ObjStr(methodObj))) { int flag = 1<definedMethods & flag) { /* * If for some reason (e.g. reload) we redefine the base * methods, these never count as overloads. */ - if ((*(Nsf_SytemMethodOpts[i]+1) == 'o' && object == &defOsPtr->rootClass->object) - || (*(Nsf_SytemMethodOpts[i]+1) == 'c' && object == &defOsPtr->rootMetaClass->object) ) { + if ((rootClassMethod && object == &defOsPtr->rootClass->object) + || (!rootClassMethod && object == &defOsPtr->rootMetaClass->object) ) { /*fprintf(stderr, "+++ %s %.6x NOT overloading %s.%s %s (is root %d, is meta %d)\n", ClassName(defOsPtr->rootClass), osPtr->overloadedMethods, ObjectName(object), methodName, Nsf_SytemMethodOpts[i], @@ -2195,9 +2195,42 @@ } } if (osPtr == defOsPtr && ((osPtr->definedMethods & flag) == 0)) { + /* + * Mark the method das defined + */ osPtr->definedMethods |= flag; /*fprintf(stderr, "+++ %s %.6x defining %s.%s %s\n", ClassName(defOsPtr->rootClass), osPtr->definedMethods, ObjectName(object), methodName, Nsf_SytemMethodOpts[i]);*/ + + /* + * If there is a method-handle provided for this system method, + * register it as a fallback unless the method being defined is + * already at the root class. + */ + if (osPtr->handles[i]) { + NsfObject *defObject = rootClassMethod + ? &osPtr->rootClass->object + : &osPtr->rootMetaClass->object; + + if (defObject != object) { + int result = NsfAliasCmd(interp, defObject, 0, methodName, 0, osPtr->handles[i]); + + NsfLog(interp, NSF_LOG_NOTICE, "Define automatically alias %s for %s", + ObjStr(osPtr->handles[i]), Nsf_SytemMethodOpts[i]); + /* + * If the definition was ok, make the method protected. + */ + if (result == TCL_OK) { + Tcl_Obj *methodObj = Tcl_GetObjResult(interp); + Tcl_Command cmd = Tcl_GetCommandFromObj(interp, methodObj); + if (cmd) { Tcl_Command_flags(cmd) |= NSF_CMD_PROTECTED_METHOD; } + Tcl_ResetResult(interp); + } else { + NsfLog(interp, NSF_LOG_WARN, "Could not define alias %s for %s", + ObjStr(osPtr->handles[i]), Nsf_SytemMethodOpts[i]); + } + } + } } } } @@ -12397,9 +12430,6 @@ return result; } -static int NsfAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, - CONST char *methodName, int withFrame, Tcl_Obj *cmdName); - static int NsfProcAliasMethod(ClientData clientData, Tcl_Interp *interp, int objc, @@ -14937,14 +14967,31 @@ return NsfPrintError(interp, "System methods must be provided as pairs"); } for (i=0; i 2) { + ObjectSystemFree(interp, osPtr); + return NsfPrintError(interp, "invalid system method argument '%s'", ObjStr(ov[i]), ObjStr(arg)); + } /*fprintf(stderr, "NsfCreateObjectSystemCmd [%d] = %p %s (max %d, given %d)\n", idx, ov[i+1], ObjStr(ov[i+1]), XO_unknown_idx, oc);*/ - osPtr->methods[idx] = ov[i+1]; + + if (arg_oc == 1) { + osPtr->methods[idx] = arg; + } else { /* (arg_oc == 2) */ + osPtr->methods[idx] = arg_ov[0]; + osPtr->handles[idx] = arg_ov[1]; + INCR_REF_COUNT(osPtr->handles[idx]); + } INCR_REF_COUNT(osPtr->methods[idx]); } } else { @@ -17152,6 +17199,17 @@ } /* +objectMethod init NsfOInitMethod { + {-argName "args" -type allargs} +} +*/ +static int +NsfOInitMethod(Tcl_Interp *UNUSED(interp), NsfObject *UNUSED(object), + int UNUSED(objc), Tcl_Obj *CONST UNUSED(objv[])) { + return TCL_OK; +} + +/* objectMethod instvar NsfOInstvarMethod { {-argName "args" -type allargs} } Index: generic/nsfInt.h =================================================================== diff -u -rc09fd1356ee0d275a8e0fa921744f052493f1a79 -r13d14668e746b4f8c6461288cdd29673db4604dd --- generic/nsfInt.h (.../nsfInt.h) (revision c09fd1356ee0d275a8e0fa921744f052493f1a79) +++ generic/nsfInt.h (.../nsfInt.h) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -603,6 +603,7 @@ int overloadedMethods; int definedMethods; Tcl_Obj *methods[NSF_o_unknown_idx+1]; + Tcl_Obj *handles[NSF_o_unknown_idx+1]; struct NsfObjectSystem *nextPtr; } NsfObjectSystem; Index: generic/tclAPI.h =================================================================== diff -u -r4536c2540977c43aaf422800dab048e5d9063b3f -r13d14668e746b4f8c6461288cdd29673db4604dd --- generic/tclAPI.h (.../tclAPI.h) (revision 4536c2540977c43aaf422800dab048e5d9063b3f) +++ generic/tclAPI.h (.../tclAPI.h) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -255,6 +255,7 @@ static int NsfODestroyMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfOExistsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfOFilterGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfOInitMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfOInstvarMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfOMixinGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfONoinitMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -340,6 +341,7 @@ static int NsfODestroyMethod(Tcl_Interp *interp, NsfObject *obj); static int NsfOExistsMethod(Tcl_Interp *interp, NsfObject *obj, CONST char *varName); static int NsfOFilterGuardMethod(Tcl_Interp *interp, NsfObject *obj, CONST char *filter, Tcl_Obj *guard); +static int NsfOInitMethod(Tcl_Interp *interp, NsfObject *obj, int objc, Tcl_Obj *CONST objv[]); static int NsfOInstvarMethod(Tcl_Interp *interp, NsfObject *obj, int objc, Tcl_Obj *CONST objv[]); static int NsfOMixinGuardMethod(Tcl_Interp *interp, NsfObject *obj, Tcl_Obj *mixin, Tcl_Obj *guard); static int NsfONoinitMethod(Tcl_Interp *interp, NsfObject *obj); @@ -426,6 +428,7 @@ NsfODestroyMethodIdx, NsfOExistsMethodIdx, NsfOFilterGuardMethodIdx, + NsfOInitMethodIdx, NsfOInstvarMethodIdx, NsfOMixinGuardMethodIdx, NsfONoinitMethodIdx, @@ -1587,6 +1590,16 @@ } static int +NsfOInitMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + NsfObject *obj = (NsfObject *)clientData; + if (!obj) return NsfObjErrType(interp, NULL, clientData ? ((NsfObject*)clientData)->cmdName : NsfGlobalObjs[NSF_EMPTY], "Object", NULL); + + + return NsfOInitMethod(interp, obj, objc, objv); + +} + +static int NsfOInstvarMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsfObject *obj = (NsfObject *)clientData; if (!obj) return NsfObjErrType(interp, NULL, clientData ? ((NsfObject*)clientData)->cmdName : NsfGlobalObjs[NSF_EMPTY], "Object", NULL); @@ -2338,6 +2351,9 @@ {"filter", NSF_ARG_REQUIRED, 0, ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"guard", NSF_ARG_REQUIRED, 0, ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::methods::object::init", NsfOInitMethodStub, 1, { + {"args", 0, 0, ConvertToNothing, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::methods::object::instvar", NsfOInstvarMethodStub, 1, { {"args", 0, 0, ConvertToNothing, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, Index: library/nx/nx.tcl =================================================================== diff -u -r0e33ba821d29af5a646fd29c2722baedddcc25b8 -r13d14668e746b4f8c6461288cdd29673db4604dd --- library/nx/nx.tcl (.../nx.tcl) (revision 0e33ba821d29af5a646fd29c2722baedddcc25b8) +++ library/nx/nx.tcl (.../nx.tcl) (revision 13d14668e746b4f8c6461288cdd29673db4604dd) @@ -20,7 +20,7 @@ -object.configure configure -object.defaultmethod defaultmethod -object.destroy destroy - -object.init init + -object.init {init ::nsf::methods::object::init} -object.move move -object.objectparameter objectparameter -object.unknown unknown @@ -38,7 +38,7 @@ foreach cmd [info command ::nsf::methods::object::*] { set cmdName [namespace tail $cmd] if {$cmdName in [list "autoname" "cleanup" "exists" \ - "filterguard" "instvar" "mixinguard" \ + "filterguard" "init" "instvar" "mixinguard" \ "noinit" "requirenamespace" "residualargs"]} continue ::nsf::method::alias Object $cmdName $cmd } @@ -267,7 +267,7 @@ # } # "init" must exist on Object. per default it is empty. - :protected method init args {} + #:protected method init args {} # this method is called on calls to object without a specified method :protected method defaultmethod {} {::nsf::self}