?? classfun.c
字號:
break; if (deletedIndex == src->classCount) return; if (src->classCount > 1) { dst.classArray = (DEFCLASS **) gm2(theEnv,(sizeof(DEFCLASS *) * (src->classCount - 1))); if (deletedIndex != 0) GenCopyMemory(DEFCLASS *,deletedIndex,dst.classArray,src->classArray); GenCopyMemory(DEFCLASS *,src->classCount - deletedIndex - 1, dst.classArray + deletedIndex,src->classArray + deletedIndex + 1); } else dst.classArray = NULL; dst.classCount = (unsigned short) (src->classCount - 1); DeletePackedClassLinks(theEnv,src,FALSE); src->classCount = dst.classCount; src->classArray = dst.classArray; }/************************************************************** NAME : NewClass DESCRIPTION : Allocates and initalizes a new class structure INPUTS : The symbolic name of the new class RETURNS : The address of the new class SIDE EFFECTS : None NOTES : None **************************************************************/globle DEFCLASS *NewClass( void *theEnv, SYMBOL_HN *className) { register DEFCLASS *cls; cls = get_struct(theEnv,defclass); InitializeConstructHeader(theEnv,"defclass",(struct constructHeader *) cls,className); cls->id = 0; cls->installed = 0; cls->busy = 0; cls->system = 0; cls->abstract = 0; cls->reactive = 1;#if DEBUGGING_FUNCTIONS cls->traceInstances = DefclassData(theEnv)->WatchInstances; cls->traceSlots = DefclassData(theEnv)->WatchSlots;#endif cls->hashTableIndex = 0; cls->directSuperclasses.classCount = 0; cls->directSuperclasses.classArray = NULL; cls->directSubclasses.classCount = 0; cls->directSubclasses.classArray = NULL; cls->allSuperclasses.classCount = 0; cls->allSuperclasses.classArray = NULL; cls->slots = NULL; cls->instanceTemplate = NULL; cls->slotNameMap = NULL; cls->instanceSlotCount = 0; cls->localInstanceSlotCount = 0; cls->slotCount = 0; cls->maxSlotNameID = 0; cls->handlers = NULL; cls->handlerOrderMap = NULL; cls->handlerCount = 0; cls->instanceList = NULL; cls->instanceListBottom = NULL; cls->nxtHash = NULL; cls->scopeMap = NULL; ClearBitString(cls->traversalRecord,TRAVERSAL_BYTES); return(cls); } /*************************************************** NAME : DeletePackedClassLinks DESCRIPTION : Dealloacates a contiguous array holding class links INPUTS : 1) The class link segment 2) A flag indicating whether to delete the top pack structure RETURNS : Nothing useful SIDE EFFECTS : Class links deallocated NOTES : None ***************************************************/globle void DeletePackedClassLinks( void *theEnv, PACKED_CLASS_LINKS *plp, int deleteTop) { if (plp->classCount > 0) { rm(theEnv,(void *) plp->classArray,(sizeof(DEFCLASS *) * plp->classCount)); plp->classCount = 0; plp->classArray = NULL; } if (deleteTop) rtn_struct(theEnv,packedClassLinks,plp); }/*************************************************** NAME : AssignClassID DESCRIPTION : Assigns a unique id to a class and puts its address in the id map INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Class id assigned and map set NOTES : None ***************************************************/globle void AssignClassID( void *theEnv, DEFCLASS *cls) { register unsigned i; if ((DefclassData(theEnv)->MaxClassID % CLASS_ID_MAP_CHUNK) == 0) { DefclassData(theEnv)->ClassIDMap = (DEFCLASS **) genrealloc(theEnv,(void *) DefclassData(theEnv)->ClassIDMap, (unsigned) (DefclassData(theEnv)->MaxClassID * sizeof(DEFCLASS *)), (unsigned) ((DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) * sizeof(DEFCLASS *))); DefclassData(theEnv)->AvailClassID += (unsigned short) CLASS_ID_MAP_CHUNK; for (i = DefclassData(theEnv)->MaxClassID ; i < (unsigned) (DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) ; i++) DefclassData(theEnv)->ClassIDMap[i] = NULL; } DefclassData(theEnv)->ClassIDMap[DefclassData(theEnv)->MaxClassID] = cls; cls->id = DefclassData(theEnv)->MaxClassID++; }/********************************************************* NAME : AddSlotName DESCRIPTION : Adds a new slot entry (or increments the use count of an existing node). INPUTS : 1) The slot name 2) The new canonical id for the slot name 3) A flag indicating whether the given id must be used or not RETURNS : The id of the (old) node SIDE EFFECTS : Slot name entry added or use count incremented NOTES : None *********************************************************/globle SLOT_NAME *AddSlotName( void *theEnv, SYMBOL_HN *slotName, int newid, int usenewid) { SLOT_NAME *snp; unsigned hashTableIndex; char *buf; size_t bufsz; hashTableIndex = HashSlotName(slotName); snp = DefclassData(theEnv)->SlotNameTable[hashTableIndex]; while ((snp != NULL) ? (snp->name != slotName) : FALSE) snp = snp->nxt; if (snp != NULL) { if (usenewid && (newid != snp->id)) { SystemError(theEnv,"CLASSFUN",1); EnvExitRouter(theEnv,EXIT_FAILURE); } snp->use++; } else { snp = get_struct(theEnv,slotName); snp->name = slotName; snp->hashTableIndex = hashTableIndex; snp->use = 1; snp->id = usenewid ? newid : NewSlotNameID(theEnv); snp->nxt = DefclassData(theEnv)->SlotNameTable[hashTableIndex]; DefclassData(theEnv)->SlotNameTable[hashTableIndex] = snp; IncrementSymbolCount(slotName); bufsz = (sizeof(char) * (PUT_PREFIX_LENGTH + strlen(ValueToString(slotName)) + 1)); buf = (char *) gm2(theEnv,bufsz); genstrcpy(buf,PUT_PREFIX); genstrcat(buf,ValueToString(slotName)); snp->putHandlerName = (SYMBOL_HN *) EnvAddSymbol(theEnv,buf); IncrementSymbolCount(snp->putHandlerName); rm(theEnv,(void *) buf,bufsz); snp->bsaveIndex = 0L; } return(snp); }/*************************************************** NAME : DeleteSlotName DESCRIPTION : Removes a slot name entry from the table of all slot names if no longer in use INPUTS : The slot name hash node RETURNS : Nothing useful SIDE EFFECTS : Slot name entry deleted or use count decremented NOTES : None ***************************************************/globle void DeleteSlotName( void *theEnv, SLOT_NAME *slotName) { SLOT_NAME *snp,*prv; if (slotName == NULL) return; prv = NULL; snp = DefclassData(theEnv)->SlotNameTable[slotName->hashTableIndex]; while (snp != slotName) { prv = snp; snp = snp->nxt; } snp->use--; if (snp->use != 0) return; if (prv == NULL) DefclassData(theEnv)->SlotNameTable[snp->hashTableIndex] = snp->nxt; else prv->nxt = snp->nxt; DecrementSymbolCount(theEnv,snp->name); DecrementSymbolCount(theEnv,snp->putHandlerName); rtn_struct(theEnv,slotName,snp); }/******************************************************************* NAME : RemoveDefclass DESCRIPTION : Deallocates a class structure and all its fields - returns all symbols in use by the class back to the symbol manager for ephemeral removal INPUTS : The address of the class RETURNS : Nothing useful SIDE EFFECTS : None NOTES : Assumes class has no subclasses IMPORTANT WARNING!! : Assumes class busy count and all instances' busy counts are 0 and all handlers' busy counts are 0! *******************************************************************/LOCALE void RemoveDefclass( void *theEnv, void *vcls) { DEFCLASS *cls = (DEFCLASS *) vcls; HANDLER *hnd; long i; /* ==================================================== Remove all of this class's superclasses' links to it ==================================================== */ for (i = 0 ; i < cls->directSuperclasses.classCount ; i++) DeleteSubclassLink(theEnv,cls->directSuperclasses.classArray[i],cls); RemoveClassFromTable(theEnv,cls); InstallClass(theEnv,cls,FALSE); DeletePackedClassLinks(theEnv,&cls->directSuperclasses,FALSE); DeletePackedClassLinks(theEnv,&cls->allSuperclasses,FALSE); DeletePackedClassLinks(theEnv,&cls->directSubclasses,FALSE); for (i = 0 ; i < cls->slotCount ; i++) { if (cls->slots[i].defaultValue != NULL) { if (cls->slots[i].dynamicDefault) ReturnPackedExpression(theEnv,(EXPRESSION *) cls->slots[i].defaultValue); else rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue); } DeleteSlotName(theEnv,cls->slots[i].slotName); RemoveConstraint(theEnv,cls->slots[i].constraint); } if (cls->instanceSlotCount != 0) { rm(theEnv,(void *) cls->instanceTemplate, (sizeof(SLOT_DESC *) * cls->instanceSlotCount)); rm(theEnv,(void *) cls->slotNameMap, (sizeof(unsigned) * (cls->maxSlotNameID + 1))); } if (cls->slotCount != 0) rm(theEnv,(void *) cls->slots,(sizeof(SLOT_DESC) * cls->slotCount)); for (i = 0 ; i < cls->handlerCount ; i++) { hnd = &cls->handlers[i]; if (hnd->actions != NULL) ReturnPackedExpression(theEnv,hnd->actions); if (hnd->ppForm != NULL) rm(theEnv,(void *) hnd->ppForm,(sizeof(char) * (strlen(hnd->ppForm)+1))); if (hnd->usrData != NULL) { ClearUserDataList(theEnv,hnd->usrData); } } if (cls->handlerCount != 0) { rm(theEnv,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount)); } SetDefclassPPForm((void *) cls,NULL); DeassignClassID(theEnv,(unsigned) cls->id); rtn_struct(theEnv,defclass,cls); } #endif /******************************************************************* NAME : DestroyDefclass DESCRIPTION : Deallocates a class structure and all its fields. INPUTS : The address of the class RETURNS : Nothing useful SIDE EFFECTS : None NOTES : *******************************************************************/LOCALE void DestroyDefclass( void *theEnv, void *vcls) { DEFCLASS *cls = (DEFCLASS *) vcls; long i;#if ! RUN_TIME HANDLER *hnd; DeletePackedClassLinks(theEnv,&cls->directSuperclasses,FALSE); DeletePackedClassLinks(theEnv,&cls->allSuperclasses,FALSE); DeletePackedClassLinks(theEnv,&cls->directSubclasses,FALSE);#endif for (i = 0 ; i < cls->slotCount ; i++) { if (cls->slots[i].defaultValue != NULL) {#if ! RUN_TIME if (cls->slots[i].dynamicDefault) ReturnPackedExpression(theEnv,(EXPRESSION *) cls->slots[i].defaultValue); else rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue);#else if (cls->slots[i].dynamicDefault == 0) rtn_struct(theEnv,dataObject,cls->slots[i].defaultValue);#endif } } #if ! RUN_TIME if (cls->instanceSlotCount != 0) { rm(theEnv,(void *) cls->instanceTemplate, (sizeof(SLOT_DESC *) * cls->instanceSlotCount)); rm(theEnv,(void *) cls->slotNameMap, (sizeof(unsigned) * (cls->maxSlotNameID + 1))); } if (cls->slotCount != 0) rm(theEnv,(void *) cls->slots,(sizeof(SLOT_DESC) * cls->slotCount)); for (i = 0 ; i < cls->handlerCount ; i++) { hnd = &cls->handlers[i]; if (hnd->actions != NULL) ReturnPackedExpression(theEnv,hnd->actions); if (hnd->ppForm != NULL) rm(theEnv,(void *) hnd->ppForm,(sizeof(char) * (strlen(hnd->ppForm)+1))); if (hnd->usrData != NULL) { ClearUserDataList(theEnv,hnd->usrData); } } if (cls->handlerCount != 0) { rm(theEnv,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount)); } DestroyConstructHeader(theEnv,&cls->header); rtn_struct(theEnv,defclass,cls);#else#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(hnd)#endif#endif } #if ! RUN_TIME/*************************************************** NAME : InstallClass DESCRIPTION : In(De)crements all symbol counts for for symbols in use by class Disallows (allows) symbols to become ephemeral. INPUTS : 1) The class address 2) 1 - install, 0 - deinstall RETURNS : Nothing useful SIDE EFFECTS : None NOTES : None ***************************************************/globle void InstallClass( void *theEnv, DEFCLASS *cls, int set) { SLOT_DESC *slot; HANDLER *hnd; long i; if ((set && cls->installed) || ((set == FALSE) && (cls->installed == 0))) return; /* ================================================================== Handler installation is handled when message-handlers are defined: see ParseDefmessageHandler() in MSGCOM.C Slot installation is handled by ParseSlot() in CLASSPSR.C Scope map installation is handled by CreateClassScopeMap() ================================================================== */ if (set == FALSE) { cls->installed = 0; DecrementSymbolCount(theEnv,cls->header.name);#if DEFMODULE_CONSTRUCT DecrementBitMapCount(theEnv,cls->scopeMap);#endif ClearUserDataList(theEnv,cls->header.usrData);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -