#include <stdlib.h>
#include "setup.h"
#if OBJECT_SYSTEM
#include "argacces.h"
#include "classcom.h"
#include "classfun.h"
#include "cstrnchk.h"
#if DEFRULE_CONSTRUCT
#include "drive.h"
#include "objrtmch.h"
#endif
#include "engine.h"
#include "envrnmnt.h"
#include "inscom.h"
#include "insmngr.h"
#include "memalloc.h"
#include "modulutl.h"
#include "msgcom.h"
#include "msgfun.h"
#include "prccode.h"
#include "prntutil.h"
#include "router.h"
#include "utility.h"
#include "insfun.h"
#define BIG_PRIME 11329
static Instance *FindImportedInstance(Environment *,Defmodule *,Defmodule *,Instance *);
#if DEFRULE_CONSTRUCT
static void NetworkModifyForSharedSlot(Environment *,int,Defclass *,SlotDescriptor *);
#endif
void IncrementInstanceCallback(
Environment *theEnv,
Instance *theInstance)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
if (theInstance == NULL) return;
theInstance->busy++;
}
void DecrementInstanceCallback(
Environment *theEnv,
Instance *theInstance)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
if (theInstance == NULL) return;
theInstance->busy--;
}
void RetainInstance(
Instance *theInstance)
{
if (theInstance == NULL) return;
theInstance->busy++;
}
void ReleaseInstance(
Instance *theInstance)
{
if (theInstance == NULL) return;
theInstance->busy--;
}
void InitializeInstanceTable(
Environment *theEnv)
{
int i;
InstanceData(theEnv)->InstanceTable = (Instance **)
gm2(theEnv,sizeof(Instance *) * INSTANCE_TABLE_HASH_SIZE);
for (i = 0 ; i < INSTANCE_TABLE_HASH_SIZE ; i++)
InstanceData(theEnv)->InstanceTable[i] = NULL;
}
void CleanupInstances(
Environment *theEnv,
void *context)
{
IGARBAGE *gprv,*gtmp,*dump;
if (InstanceData(theEnv)->MaintainGarbageInstances)
return;
gprv = NULL;
gtmp = InstanceData(theEnv)->InstanceGarbageList;
while (gtmp != NULL)
{
#if DEFRULE_CONSTRUCT
if ((gtmp->ins->busy == 0)
&& (gtmp->ins->patternHeader.busyCount == 0))
#else
if (gtmp->ins->busy == 0)
#endif
{
ReleaseLexeme(theEnv,gtmp->ins->name);
rtn_struct(theEnv,instance,gtmp->ins);
if (gprv == NULL)
InstanceData(theEnv)->InstanceGarbageList = gtmp->nxt;
else
gprv->nxt = gtmp->nxt;
dump = gtmp;
gtmp = gtmp->nxt;
rtn_struct(theEnv,igarbage,dump);
}
else
{
gprv = gtmp;
gtmp = gtmp->nxt;
}
}
}
unsigned HashInstance(
CLIPSLexeme *cname)
{
unsigned long tally;
tally = ((unsigned long) cname->bucket) * BIG_PRIME;
return (unsigned) (tally % INSTANCE_TABLE_HASH_SIZE);
}
void DestroyAllInstances(
Environment *theEnv,
void *context)
{
Instance *iptr;
bool svmaintain;
SaveCurrentModule(theEnv);
svmaintain = InstanceData(theEnv)->MaintainGarbageInstances;
InstanceData(theEnv)->MaintainGarbageInstances = true;
iptr = InstanceData(theEnv)->InstanceList;
while (iptr != NULL)
{
SetCurrentModule(theEnv,iptr->cls->header.whichModule->theModule);
DirectMessage(theEnv,MessageHandlerData(theEnv)->DELETE_SYMBOL,iptr,NULL,NULL);
iptr = iptr->nxtList;
while ((iptr != NULL) ? iptr->garbage : false)
iptr = iptr->nxtList;
}
InstanceData(theEnv)->MaintainGarbageInstances = svmaintain;
RestoreCurrentModule(theEnv);
}
void RemoveInstanceData(
Environment *theEnv,
Instance *ins)
{
long i;
InstanceSlot *sp;
DecrementDefclassBusyCount(theEnv,ins->cls);
for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
{
sp = ins->slotAddresses[i];
if ((sp == &sp->desc->sharedValue) ?
(--sp->desc->sharedCount == 0) : true)
{
if (sp->desc->multiple)
{
ReleaseMultifield(theEnv,sp->multifieldValue);
AddToMultifieldList(theEnv,sp->multifieldValue);
}
else
AtomDeinstall(theEnv,sp->type,sp->value);
sp->value = NULL;
}
}
if (ins->cls->instanceSlotCount != 0)
{
rm(theEnv,ins->slotAddresses,
(ins->cls->instanceSlotCount * sizeof(InstanceSlot *)));
if (ins->cls->localInstanceSlotCount != 0)
rm(theEnv,ins->slots,
(ins->cls->localInstanceSlotCount * sizeof(InstanceSlot)));
}
ins->slots = NULL;
ins->slotAddresses = NULL;
}
Instance *FindInstanceBySymbol(
Environment *theEnv,
CLIPSLexeme *moduleAndInstanceName)
{
unsigned modulePosition;
bool searchImports;
CLIPSLexeme *moduleName, *instanceName;
Defmodule *currentModule,*theModule;
currentModule = GetCurrentModule(theEnv);
modulePosition = FindModuleSeparator(moduleAndInstanceName->contents);
if (modulePosition == 0)
{
Instance *ins;
if (moduleAndInstanceName->header.type == SYMBOL_TYPE)
{ moduleAndInstanceName = CreateInstanceName(theEnv,moduleAndInstanceName->contents); }
ins = InstanceData(theEnv)->InstanceTable[HashInstance(moduleAndInstanceName)];
while (ins != NULL)
{
if (ins->name == moduleAndInstanceName)
{ return ins; }
ins = ins->nxtHash;
}
return NULL;
}
else if (modulePosition == 1)
{
theModule = currentModule;
instanceName = ExtractConstructName(theEnv,modulePosition,moduleAndInstanceName->contents,INSTANCE_NAME_TYPE);
searchImports = true;
}
else
{
moduleName = ExtractModuleName(theEnv,modulePosition,moduleAndInstanceName->contents);
theModule = FindDefmodule(theEnv,moduleName->contents);
instanceName = ExtractConstructName(theEnv,modulePosition,moduleAndInstanceName->contents,INSTANCE_NAME_TYPE);
if (theModule == NULL)
return NULL;
searchImports = false;
}
return(FindInstanceInModule(theEnv,instanceName,theModule,currentModule,searchImports));
}
Instance *FindInstanceInModule(
Environment *theEnv,
CLIPSLexeme *instanceName,
Defmodule *theModule,
Defmodule *currentModule,
bool searchImports)
{
Instance *startInstance,*ins;
startInstance = InstanceData(theEnv)->InstanceTable[HashInstance(instanceName)];
while (startInstance != NULL)
{
if (startInstance->name == instanceName)
break;
startInstance = startInstance->nxtHash;
}
if (startInstance == NULL)
return NULL;
for (ins = startInstance ;
(ins != NULL) ? (ins->name == startInstance->name) : false ;
ins = ins->nxtHash)
if (ins->cls->header.whichModule->theModule == theModule)
return(ins);
if (searchImports == false)
return NULL;
MarkModulesAsUnvisited(theEnv);
return(FindImportedInstance(theEnv,theModule,currentModule,startInstance));
}
InstanceSlot *FindInstanceSlot(
Environment *theEnv,
Instance *ins,
CLIPSLexeme *sname)
{
int i;
i = FindInstanceTemplateSlot(theEnv,ins->cls,sname);
return (i != -1) ? ins->slotAddresses[i] : NULL;
}
int FindInstanceTemplateSlot(
Environment *theEnv,
Defclass *cls,
CLIPSLexeme *sname)
{
unsigned short sid;
sid = FindSlotNameID(theEnv,sname);
if (sid == SLOT_NAME_NOT_FOUND)
return -1;
if (sid > cls->maxSlotNameID)
return -1;
return((int) cls->slotNameMap[sid] - 1);
}
PutSlotError PutSlotValue(
Environment *theEnv,
Instance *ins,
InstanceSlot *sp,
UDFValue *val,
UDFValue *setVal,
const char *theCommand)
{
PutSlotError rv;
if ((rv = ValidSlotValue(theEnv,val,sp->desc,ins,theCommand)) != PSE_NO_ERROR)
{
setVal->value = FalseSymbol(theEnv);
return rv;
}
return DirectPutSlotValue(theEnv,ins,sp,val,setVal);
}
PutSlotError DirectPutSlotValue(
Environment *theEnv,
Instance *ins,
InstanceSlot *sp,
UDFValue *val,
UDFValue *setVal)
{
size_t i,j;
#if DEFRULE_CONSTRUCT
int sharedTraversalID;
InstanceSlot *bsp,**spaddr;
#endif
UDFValue tmpVal;
setVal->value = FalseSymbol(theEnv);
if (val == NULL)
{
SystemError(theEnv,"INSFUN",1);
ExitRouter(theEnv,EXIT_FAILURE);
}
else if (val->value == ProceduralPrimitiveData(theEnv)->NoParamValue)
{
if (sp->desc->dynamicDefault)
{
val = &tmpVal;
if (!EvaluateAndStoreInDataObject(theEnv,sp->desc->multiple,
(Expression *) sp->desc->defaultValue,val,true))
return PSE_EVALUATION_ERROR;
}
else if (sp->desc->defaultValue != NULL)
{ val = (UDFValue *) sp->desc->defaultValue; }
else
{
PrintErrorID(theEnv,"INSMNGR",14,false);
WriteString(theEnv,STDERR,"Override required for slot '");
WriteString(theEnv,STDERR,sp->desc->slotName->name->contents);
WriteString(theEnv,STDERR,"' in instance [");
WriteString(theEnv,STDERR,ins->name->contents);
WriteString(theEnv,STDERR,"].\n");
SetEvaluationError(theEnv,true);
return PSE_EVALUATION_ERROR;
}
}
#if DEFRULE_CONSTRUCT
if (EngineData(theEnv)->JoinOperationInProgress && sp->desc->reactive &&
(ins->cls->reactive || sp->desc->shared))
{
PrintErrorID(theEnv,"INSFUN",5,false);
WriteString(theEnv,STDERR,"Cannot modify reactive instance slots while ");
WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
SetEvaluationError(theEnv,true);
return PSE_RULE_NETWORK_ERROR;
}
if (ins->basisSlots != NULL)
{
spaddr = &ins->slotAddresses[ins->cls->slotNameMap[sp->desc->slotName->id] - 1];
bsp = ins->basisSlots + (spaddr - ins->slotAddresses);
if (bsp->value == NULL)
{
bsp->type = sp->type;
bsp->value = sp->value;
if (sp->desc->multiple)
RetainMultifield(theEnv,bsp->multifieldValue);
else
AtomInstall(theEnv,bsp->type,bsp->value);
}
}
#endif
if (sp->desc->multiple == 0)
{
AtomDeinstall(theEnv,sp->type,sp->value);
if (val->header->type == MULTIFIELD_TYPE)
{
sp->type = val->multifieldValue->contents[val->begin].header->type;
sp->value = val->multifieldValue->contents[val->begin].value;
}
else
{
sp->type = val->header->type;
sp->value = val->value;
}
AtomInstall(theEnv,sp->type,sp->value);
setVal->value = sp->value;
}
else
{
ReleaseMultifield(theEnv,sp->multifieldValue);
AddToMultifieldList(theEnv,sp->multifieldValue);
sp->type = MULTIFIELD_TYPE;
if (val->header->type == MULTIFIELD_TYPE)
{
sp->value = CreateUnmanagedMultifield(theEnv,(unsigned long) val->range);
for (i = 0 , j = val->begin ; i < val->range ; i++ , j++)
{
sp->multifieldValue->contents[i].value = val->multifieldValue->contents[j].value;
}
}
else
{
sp->multifieldValue = CreateUnmanagedMultifield(theEnv,1L);
sp->multifieldValue->contents[0].value = val->value;
}
RetainMultifield(theEnv,sp->multifieldValue);
setVal->value = sp->value;
setVal->begin = 0;
setVal->range = sp->multifieldValue->length;
}
sp->override = ins->initializeInProgress;
#if DEBUGGING_FUNCTIONS
if (ins->cls->traceSlots &&
(! ConstructData(theEnv)->ClearReadyInProgress) &&
(! ConstructData(theEnv)->ClearInProgress))
{
if (sp->desc->shared)
WriteString(theEnv,STDOUT,"::= shared slot ");
else
WriteString(theEnv,STDOUT,"::= local slot ");
WriteString(theEnv,STDOUT,sp->desc->slotName->name->contents);
WriteString(theEnv,STDOUT," in instance ");
WriteString(theEnv,STDOUT,ins->name->contents);
WriteString(theEnv,STDOUT," <- ");
if (sp->type != MULTIFIELD_TYPE)
PrintAtom(theEnv,STDOUT,sp->type,sp->value);
else
PrintMultifieldDriver(theEnv,STDOUT,sp->multifieldValue,0,
sp->multifieldValue->length,true);
WriteString(theEnv,STDOUT,"\n");
}
#endif
InstanceData(theEnv)->ChangesToInstances = true;
#if DEFRULE_CONSTRUCT
if (ins->cls->reactive && sp->desc->reactive)
{
if (sp->desc->shared)
{
sharedTraversalID = GetTraversalID(theEnv);
if (sharedTraversalID != -1)
{
NetworkModifyForSharedSlot(theEnv,sharedTraversalID,sp->desc->cls,sp->desc);
ReleaseTraversalID(theEnv);
}
else
{
PrintErrorID(theEnv,"INSFUN",6,false);
WriteString(theEnv,STDERR,"Unable to pattern-match on shared slot '");
WriteString(theEnv,STDERR,sp->desc->slotName->name->contents);
WriteString(theEnv,STDERR,"' in class '");
WriteString(theEnv,STDERR,DefclassName(sp->desc->cls));
WriteString(theEnv,STDERR,"'.\n");
return PSE_RULE_NETWORK_ERROR;
}
}
else
ObjectNetworkAction(theEnv,OBJECT_MODIFY,ins,(int) sp->desc->slotName->id);
}
#endif
return PSE_NO_ERROR;
}
PutSlotError ValidSlotValue(
Environment *theEnv,
UDFValue *val,
SlotDescriptor *sd,
Instance *ins,
const char *theCommand)
{
ConstraintViolationType violationCode;
if (val->value == ProceduralPrimitiveData(theEnv)->NoParamValue)
return PSE_NO_ERROR;
if ((sd->multiple == 0) && (val->header->type == MULTIFIELD_TYPE) &&
(val->range != 1))
{
PrintErrorID(theEnv,"INSFUN",7,false);
WriteString(theEnv,STDERR,"The value ");
WriteUDFValue(theEnv,STDERR,val);
WriteString(theEnv,STDERR," is illegal for single-field ");
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
WriteString(theEnv,STDERR,".\n");
SetEvaluationError(theEnv,true);
return PSE_CARDINALITY_ERROR;
}
if (val->header->type == VOID_TYPE)
{
PrintErrorID(theEnv,"INSFUN",8,false);
WriteString(theEnv,STDERR,"Void function illegal value for ");
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
WriteString(theEnv,STDERR,".\n");
SetEvaluationError(theEnv,true);
return PSE_CARDINALITY_ERROR;
}
if (GetDynamicConstraintChecking(theEnv))
{
violationCode = ConstraintCheckDataObject(theEnv,val,sd->constraint);
if (violationCode != NO_VIOLATION)
{
PrintErrorID(theEnv,"CSTRNCHK",1,false);
WriteString(theEnv,STDERR,"The value ");
if ((val->header->type == MULTIFIELD_TYPE) && (sd->multiple == 0))
PrintAtom(theEnv,STDERR,val->multifieldValue->contents[val->begin].header->type,
val->multifieldValue->contents[val->begin].value);
else
WriteUDFValue(theEnv,STDERR,val);
WriteString(theEnv,STDERR," for ");
PrintSlot(theEnv,STDERR,sd,ins,theCommand);
ConstraintViolationErrorMessage(theEnv,NULL,NULL,0,0,NULL,0,
violationCode,sd->constraint,false);
SetEvaluationError(theEnv,true);
switch(violationCode)
{
case NO_VIOLATION:
SystemError(theEnv,"FACTMNGR",2);
ExitRouter(theEnv,EXIT_FAILURE);
break;
case FUNCTION_RETURN_TYPE_VIOLATION:
case TYPE_VIOLATION:
return PSE_TYPE_ERROR;
case RANGE_VIOLATION:
return PSE_RANGE_ERROR;
case ALLOWED_VALUES_VIOLATION:
return PSE_ALLOWED_VALUES_ERROR;
case CARDINALITY_VIOLATION:
return PSE_CARDINALITY_ERROR;
case ALLOWED_CLASSES_VIOLATION:
return PSE_ALLOWED_CLASSES_ERROR;
}
}
}
return PSE_NO_ERROR;
}
Instance *CheckInstance(
UDFContext *context)
{
Instance *ins;
UDFValue temp;
Environment *theEnv = context->environment;
UDFFirstArgument(context,ANY_TYPE_BITS,&temp);
if (temp.header->type == INSTANCE_ADDRESS_TYPE)
{
ins = temp.instanceValue;
if (ins->garbage == 1)
{
StaleInstanceAddress(theEnv,UDFContextFunctionName(context),0);
SetEvaluationError(theEnv,true);
return NULL;
}
}
else if (temp.header->type == INSTANCE_NAME_TYPE)
{
ins = FindInstanceBySymbol(theEnv,temp.lexemeValue);
if (ins == NULL)
{
NoInstanceError(theEnv,temp.lexemeValue->contents,UDFContextFunctionName(context));
return NULL;
}
}
else if (temp.header->type == SYMBOL_TYPE)
{
temp.value = CreateInstanceName(theEnv,temp.lexemeValue->contents);
ins = FindInstanceBySymbol(theEnv,temp.lexemeValue);
if (ins == NULL)
{
NoInstanceError(theEnv,temp.lexemeValue->contents,UDFContextFunctionName(context));
return NULL;
}
}
else
{
PrintErrorID(theEnv,"INSFUN",1,false);
WriteString(theEnv,STDERR,"Expected a valid instance in function '");
WriteString(theEnv,STDERR,UDFContextFunctionName(context));
WriteString(theEnv,STDERR,"'.\n");
SetEvaluationError(theEnv,true);
return NULL;
}
return(ins);
}
void NoInstanceError(
Environment *theEnv,
const char *iname,
const char *func)
{
PrintErrorID(theEnv,"INSFUN",2,false);
WriteString(theEnv,STDERR,"No such instance [");
WriteString(theEnv,STDERR,iname);
WriteString(theEnv,STDERR,"] in function '");
WriteString(theEnv,STDERR,func);
WriteString(theEnv,STDERR,"'.\n");
SetEvaluationError(theEnv,true);
}
void StaleInstanceAddress(
Environment *theEnv,
const char *func,
int whichArg)
{
PrintErrorID(theEnv,"INSFUN",4,false);
WriteString(theEnv,STDERR,"Invalid instance-address in function '");
WriteString(theEnv,STDERR,func);
WriteString(theEnv,STDERR,"'");
if (whichArg > 0)
{
WriteString(theEnv,STDERR,", argument #");
WriteInteger(theEnv,STDERR,whichArg);
}
WriteString(theEnv,STDERR,".\n");
}
bool GetInstancesChanged(
Environment *theEnv)
{
return InstanceData(theEnv)->ChangesToInstances;
}
void SetInstancesChanged(
Environment *theEnv,
bool changed)
{
InstanceData(theEnv)->ChangesToInstances = changed;
}
void PrintSlot(
Environment *theEnv,
const char *logName,
SlotDescriptor *sd,
Instance *ins,
const char *theCommand)
{
WriteString(theEnv,logName,"slot '");
WriteString(theEnv,logName,sd->slotName->name->contents);
WriteString(theEnv,logName,"'");
if (ins != NULL)
{
WriteString(theEnv,logName," of instance [");
WriteString(theEnv,logName,ins->name->contents);
WriteString(theEnv,logName,"]");
}
else if (sd->cls != NULL)
{
WriteString(theEnv,logName," of class '");
WriteString(theEnv,logName,DefclassName(sd->cls));
WriteString(theEnv,logName," of class '");
}
WriteString(theEnv,logName," found in ");
if (theCommand != NULL)
WriteString(theEnv,logName,theCommand);
else
PrintHandler(theEnv,logName,MessageHandlerData(theEnv)->CurrentCore->hnd,true,false);
}
void PrintInstanceNameAndClass(
Environment *theEnv,
const char *logicalName,
Instance *theInstance,
bool linefeedFlag)
{
WriteString(theEnv,logicalName,"[");
WriteString(theEnv,logicalName,InstanceName(theInstance));
WriteString(theEnv,logicalName,"] of ");
PrintClassName(theEnv,logicalName,theInstance->cls,false,linefeedFlag);
}
void PrintInstanceName(
Environment *theEnv,
const char *logName,
Instance *theInstance)
{
if (theInstance->garbage)
{
WriteString(theEnv,logName,"<stale instance [");
WriteString(theEnv,logName,theInstance->name->contents);
WriteString(theEnv,logName,"]>");
}
else
{
WriteString(theEnv,logName,"[");
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
WriteString(theEnv,logName,"]");
}
}
void PrintInstanceLongForm(
Environment *theEnv,
const char *logName,
Instance *theInstance)
{
if (PrintUtilityData(theEnv)->InstanceAddressesToNames)
{
if (theInstance == &InstanceData(theEnv)->DummyInstance)
WriteString(theEnv,logName,"\"<Dummy Instance>\"");
else
{
WriteString(theEnv,logName,"[");
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
WriteString(theEnv,logName,"]");
}
}
else
{
if (PrintUtilityData(theEnv)->AddressesToStrings)
WriteString(theEnv,logName,"\"");
if (theInstance == &InstanceData(theEnv)->DummyInstance)
WriteString(theEnv,logName,"<Dummy Instance>");
else if (theInstance->garbage)
{
WriteString(theEnv,logName,"<Stale Instance-");
WriteString(theEnv,logName,theInstance->name->contents);
WriteString(theEnv,logName,">");
}
else
{
WriteString(theEnv,logName,"<Instance-");
WriteString(theEnv,logName,GetFullInstanceName(theEnv,theInstance)->contents);
WriteString(theEnv,logName,">");
}
if (PrintUtilityData(theEnv)->AddressesToStrings)
WriteString(theEnv,logName,"\"");
}
}
#if DEFRULE_CONSTRUCT
void DecrementObjectBasisCount(
Environment *theEnv,
Instance *theInstance)
{
long i;
theInstance->patternHeader.busyCount--;
if (theInstance->patternHeader.busyCount == 0)
{
if (theInstance->garbage)
RemoveInstanceData(theEnv,theInstance);
if (theInstance->cls->instanceSlotCount != 0)
{
for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
if (theInstance->basisSlots[i].value != NULL)
{
if (theInstance->basisSlots[i].desc->multiple)
ReleaseMultifield(theEnv,theInstance->basisSlots[i].multifieldValue);
else
AtomDeinstall(theEnv,theInstance->basisSlots[i].type,
theInstance->basisSlots[i].value);
}
rm(theEnv,theInstance->basisSlots,
(theInstance->cls->instanceSlotCount * sizeof(InstanceSlot)));
theInstance->basisSlots = NULL;
}
}
}
void IncrementObjectBasisCount(
Environment *theEnv,
Instance *theInstance)
{
long i;
if (theInstance->patternHeader.busyCount == 0)
{
if (theInstance->cls->instanceSlotCount != 0)
{
theInstance->basisSlots = (InstanceSlot *)
gm2(theEnv,(sizeof(InstanceSlot) * theInstance->cls->instanceSlotCount));
for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
{
theInstance->basisSlots[i].desc = theInstance->slotAddresses[i]->desc;
theInstance->basisSlots[i].value = NULL;
}
}
}
theInstance->patternHeader.busyCount++;
}
void MatchObjectFunction(
Environment *theEnv,
Instance *theInstance)
{
ObjectNetworkAction(theEnv,OBJECT_ASSERT,theInstance,-1);
}
bool NetworkSynchronized(
Environment *theEnv,
Instance *theInstance)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
return theInstance->reteSynchronized;
}
bool InstanceIsDeleted(
Environment *theEnv,
Instance *theInstance)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
return theInstance->garbage;
}
#endif
static Instance *FindImportedInstance(
Environment *theEnv,
Defmodule *theModule,
Defmodule *currentModule,
Instance *startInstance)
{
struct portItem *importList;
Instance *ins;
if (theModule->visitedFlag)
return NULL;
theModule->visitedFlag = true;
importList = theModule->importList;
while (importList != NULL)
{
theModule = FindDefmodule(theEnv,importList->moduleName->contents);
for (ins = startInstance ;
(ins != NULL) ? (ins->name == startInstance->name) : false ;
ins = ins->nxtHash)
if ((ins->cls->header.whichModule->theModule == theModule) &&
DefclassInScope(theEnv,ins->cls,currentModule))
return(ins);
ins = FindImportedInstance(theEnv,theModule,currentModule,startInstance);
if (ins != NULL)
return(ins);
importList = importList->next;
}
for (ins = startInstance ;
(ins != NULL) ? (ins->name == startInstance->name) : false ;
ins = ins->nxtHash)
if (ins->cls->system)
return(ins);
return NULL;
}
#if DEFRULE_CONSTRUCT
static void NetworkModifyForSharedSlot(
Environment *theEnv,
int sharedTraversalID,
Defclass *cls,
SlotDescriptor *sd)
{
Instance *ins;
unsigned long i;
if (TestTraversalID(cls->traversalRecord,sharedTraversalID))
return;
SetTraversalID(cls->traversalRecord,sharedTraversalID);
if ((sd->slotName->id > cls->maxSlotNameID) ? false :
((cls->slotNameMap[sd->slotName->id] == 0) ? false :
(cls->instanceTemplate[cls->slotNameMap[sd->slotName->id] - 1] == sd)))
{
for (ins = cls->instanceList ; ins != NULL ; ins = ins->nxtClass)
ObjectNetworkAction(theEnv,OBJECT_MODIFY,ins,(int) sd->slotName->id);
}
for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
NetworkModifyForSharedSlot(theEnv,sharedTraversalID,cls->directSubclasses.classArray[i],sd);
}
#endif
#endif