Index: TODO =================================================================== diff -u -r99c7e7c4351ea0c17971fa41bd5d3c0f5a4c0321 -r08ec3c401fec6ee6e7358da7f75a3208308d8b6b --- TODO (.../TODO) (revision 99c7e7c4351ea0c17971fa41bd5d3c0f5a4c0321) +++ TODO (.../TODO) (revision 08ec3c401fec6ee6e7358da7f75a3208308d8b6b) @@ -5363,6 +5363,13 @@ working on the root classes (an more efficient on subclasses). - added experimental code feature CYCLIC_MIXIN_ERROR +nsf.c: +- improve performance of MixinInvalidateObjOrders() by about 30% + by recomping the list of the dependent classes over and over again, + since MixinInvalidateObjOrders() iterates over the full list already. +- Document NsfRelationClassMixinsSet() and add nonnull declarations and + the usual assertions() + ======================================================================== TODO: @@ -5372,7 +5379,6 @@ if we disallow cycles in class-mixins, we can't do "nx::Object mixin add M" -- Document/nonnull/resolve NsfRelationClassMixinsSet() - check other places whether DependentSubClasses() should be used instead of TransitiveSubClasses() Index: generic/nsf.c =================================================================== diff -u -r99c7e7c4351ea0c17971fa41bd5d3c0f5a4c0321 -r08ec3c401fec6ee6e7358da7f75a3208308d8b6b --- generic/nsf.c (.../nsf.c) (revision 99c7e7c4351ea0c17971fa41bd5d3c0f5a4c0321) +++ generic/nsf.c (.../nsf.c) (revision 08ec3c401fec6ee6e7358da7f75a3208308d8b6b) @@ -340,6 +340,7 @@ nonnull(1) nonnull(2) nonnull(3); static void ParamDefsRefCountIncr(NsfParamDefs *paramDefs) nonnull(1); static void ParamDefsRefCountDecr(NsfParamDefs *paramDefs) nonnull(1); +static void ParsedParamFree(NsfParsedParam *parsedParamPtr) nonnull(1); static int ArgumentParse(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], NsfObject *obj, Tcl_Obj *procName, @@ -8864,19 +8865,19 @@ for (hPtr = Tcl_FirstHashEntry(commandTable, &hSrch); hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { NsfClass *ncl = (NsfClass *)Tcl_GetHashKey(commandTable, hPtr); - /*fprintf(stderr, "Got %s, reset for ncl %p\n", ncl?ClassName(ncl):"NULL", ncl);*/ - if (ncl) { - int result; + if (ncl) { MixinResetOrderForInstances(ncl); /* - * This place seems to be sufficient to invalidate the computed object - * parameter definitions. + * Here it is sufficient to invalidate the computed configure parameter + * definitions without calling the full-blown + * NsfParameterCacheClassInvalidateCmd(interp, ncl), since we are + * iterating over the full relevant class ist. */ - /*fprintf(stderr, "MixinInvalidateObjOrders via class mixin %s calls ifd invalidate \n", ClassName(ncl));*/ - result = NsfParameterCacheClassInvalidateCmd(interp, ncl); - (void) result; // silence compiler - //fprintf(stderr, "MixinInvalidateObjOrders calls NsfParameterCacheClassInvalidateCmd %s => %d\n", ClassName(ncl), result); + if (ncl->parsedParamPtr) { + ParsedParamFree(ncl->parsedParamPtr); + ncl->parsedParamPtr = NULL; + } } } Tcl_DeleteHashTable(commandTable); @@ -11853,8 +11854,6 @@ * *---------------------------------------------------------------------- */ -static void ParsedParamFree(NsfParsedParam *parsedParamPtr) nonnull(1); - static void ParsedParamFree(NsfParsedParam *parsedParamPtr) { @@ -25804,14 +25803,35 @@ } +/* + *---------------------------------------------------------------------- + * NsfRelationClassMixinsSet -- + * + * Set class mixins; the main reason for the factored out semantics is that + * it can allow to undo/redo the operations in case of a failure. + * + * Results: + * Tcl result code. + * + * Side effects: + * class mixins are set, various kinds of invlidations. + * + *---------------------------------------------------------------------- + */ +static int NsfRelationClassMixinsSet(Tcl_Interp *interp, NsfClass *cl, Tcl_Obj *valueObj, int oc, Tcl_Obj **ov) + nonnull(1) nonnull(2) nonnull(3); + static int NsfRelationClassMixinsSet(Tcl_Interp *interp, NsfClass *cl, Tcl_Obj *valueObj, int oc, Tcl_Obj **ov) { NsfCmdList *newMixinCmdList = NULL, *cmds; NsfClasses *subClasses; NsfClassOpt *clopt = cl->opt; int i; + assert(interp); + assert(cl); assert(clopt); + assert(valueObj); for (i = 0; i < oc; i++) { if (MixinAdd(interp, &newMixinCmdList, ov[i], cl->object.cl) != TCL_OK) {