📄 insmngr.c
字号:
********************************************************/
static void InstallInstance(
void *theEnv,
INSTANCE_TYPE *ins,
int set)
{
if (set == TRUE)
{
if (ins->installed)
return;
#if DEBUGGING_FUNCTIONS
if (ins->cls->traceInstances)
PrintInstanceWatch(theEnv,MAKE_TRACE,ins);
#endif
ins->installed = 1;
ins->depth = EvaluationData(theEnv)->CurrentEvaluationDepth;
IncrementSymbolCount(ins->name);
IncrementDefclassBusyCount(theEnv,(void *) ins->cls);
InstanceData(theEnv)->GlobalNumberOfInstances++;
}
else
{
if (! ins->installed)
return;
ins->installed = 0;
InstanceData(theEnv)->GlobalNumberOfInstances--;
/* =======================================
Class counts is decremented by
RemoveInstanceData() when slot data is
truly deleted - and name count is
deleted by CleanupInstances() or
QuashInstance() when instance is
truly deleted
======================================= */
}
}
/****************************************************************
NAME : BuildDefaultSlots
DESCRIPTION : The current instance's address is
in the global variable CurrentInstance.
This builds the slots and the default values
from the direct class of the instance and its
inheritances.
INPUTS : Flag indicating whether init message will be
called for this instance or not
RETURNS : Nothing useful
SIDE EFFECTS : Allocates the slot array for
the current instance
NOTES : The current instance's address is
stored in a global variable
****************************************************************/
static void BuildDefaultSlots(
void *theEnv,
intBool initMessage)
{
register unsigned i,j;
unsigned scnt;
unsigned lscnt;
INSTANCE_SLOT *dst = NULL,**adst;
SLOT_DESC **src;
scnt = InstanceData(theEnv)->CurrentInstance->cls->instanceSlotCount;
lscnt = InstanceData(theEnv)->CurrentInstance->cls->localInstanceSlotCount;
if (scnt > 0)
{
InstanceData(theEnv)->CurrentInstance->slotAddresses = adst =
(INSTANCE_SLOT **) gm2(theEnv,(sizeof(INSTANCE_SLOT *) * scnt));
if (lscnt != 0)
InstanceData(theEnv)->CurrentInstance->slots = dst =
(INSTANCE_SLOT *) gm2(theEnv,(sizeof(INSTANCE_SLOT) * lscnt));
src = InstanceData(theEnv)->CurrentInstance->cls->instanceTemplate;
/* ==================================================
A map of slot addresses is created - shared slots
point at values in the class, and local slots
point at values in the instance
Also - slots are always given an initial value
(since slots cannot be unbound). If there is
already an instance of a class with a shared slot,
that value is left alone
================================================== */
for (i = 0 , j = 0 ; i < scnt ; i++)
{
if (src[i]->shared)
{
src[i]->sharedCount++;
adst[i] = &(src[i]->sharedValue);
}
else
{
dst[j].desc = src[i];
dst[j].value = NULL;
adst[i] = &dst[j++];
}
if (adst[i]->value == NULL)
{
adst[i]->valueRequired = initMessage;
if (adst[i]->desc->multiple)
{
adst[i]->type = MULTIFIELD;
adst[i]->value = CreateMultifield2(theEnv,0L);
MultifieldInstall(theEnv,(MULTIFIELD_PTR) adst[i]->value);
}
else
{
adst[i]->type = SYMBOL;
adst[i]->value = EnvAddSymbol(theEnv,"nil");
AtomInstall(theEnv,(int) adst[i]->type,adst[i]->value);
}
}
else
adst[i]->valueRequired = FALSE;
adst[i]->override = FALSE;
}
}
}
/*******************************************************************
NAME : CoreInitializeInstance
DESCRIPTION : Performs the core work for initializing an instance
INPUTS : 1) The instance address
2) Slot override expressions
RETURNS : TRUE if all OK, FALSE otherwise
SIDE EFFECTS : EvaluationError set on errors - slots evaluated
NOTES : None
*******************************************************************/
static int CoreInitializeInstance(
void *theEnv,
INSTANCE_TYPE *ins,
EXPRESSION *ovrexp)
{
DATA_OBJECT temp;
if (ins->installed == 0)
{
PrintErrorID(theEnv,"INSMNGR",7,FALSE);
EnvPrintRouter(theEnv,WERROR,"Instance ");
EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name));
EnvPrintRouter(theEnv,WERROR," is already being initialized.\n");
SetEvaluationError(theEnv,TRUE);
return(FALSE);
}
/* =======================================================
Replace all default-slot values with any slot-overrides
======================================================= */
ins->busy++;
ins->installed = 0;
/* =================================================================
If the slots are initialized properly - the initializeInProgress
flag will be turned off.
================================================================= */
ins->initializeInProgress = 1;
ins->initSlotsCalled = 0;
if (InsertSlotOverrides(theEnv,ins,ovrexp) == FALSE)
{
ins->installed = 1;
ins->busy--;
return(FALSE);
}
/* =================================================================
Now that all the slot expressions are established - replace them
with their evaluation
================================================================= */
if (InstanceData(theEnv)->MkInsMsgPass)
DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,ins,&temp,NULL);
else
EvaluateClassDefaults(theEnv,ins);
ins->busy--;
ins->installed = 1;
if (EvaluationData(theEnv)->EvaluationError)
{
PrintErrorID(theEnv,"INSMNGR",8,FALSE);
EnvPrintRouter(theEnv,WERROR,"An error occurred during the initialization of instance ");
EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name));
EnvPrintRouter(theEnv,WERROR,".\n");
return(FALSE);
}
ins->initializeInProgress = 0;
return((ins->initSlotsCalled == 0) ? FALSE : TRUE);
}
/**********************************************************
NAME : InsertSlotOverrides
DESCRIPTION : Replaces value-expression for a slot
INPUTS : 1) The instance address
2) The address of the beginning of the
list of slot-expressions
RETURNS : TRUE if all okay, FALSE otherwise
SIDE EFFECTS : Old slot expression deallocated
NOTES : Assumes symbols not yet installed
EVALUATES the slot-name expression but
simply copies the slot value-expression
**********************************************************/
static int InsertSlotOverrides(
void *theEnv,
INSTANCE_TYPE *ins,
EXPRESSION *slot_exp)
{
INSTANCE_SLOT *slot;
DATA_OBJECT temp,junk;
EvaluationData(theEnv)->EvaluationError = FALSE;
while (slot_exp != NULL)
{
if ((EvaluateExpression(theEnv,slot_exp,&temp) == TRUE) ? TRUE :
(GetType(temp) != SYMBOL))
{
PrintErrorID(theEnv,"INSMNGR",9,FALSE);
EnvPrintRouter(theEnv,WERROR,"Expected a valid slot name for slot-override.\n");
SetEvaluationError(theEnv,TRUE);
return(FALSE);
}
slot = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) GetValue(temp));
if (slot == NULL)
{
PrintErrorID(theEnv,"INSMNGR",13,FALSE);
EnvPrintRouter(theEnv,WERROR,"Slot ");
EnvPrintRouter(theEnv,WERROR,DOToString(temp));
EnvPrintRouter(theEnv,WERROR," does not exist in instance ");
EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name));
EnvPrintRouter(theEnv,WERROR,".\n");
SetEvaluationError(theEnv,TRUE);
return(FALSE);
}
if (InstanceData(theEnv)->MkInsMsgPass)
{ DirectMessage(theEnv,slot->desc->overrideMessage,
ins,NULL,slot_exp->nextArg->argList); }
else if (slot_exp->nextArg->argList)
{
if (EvaluateAndStoreInDataObject(theEnv,(int) slot->desc->multiple,
slot_exp->nextArg->argList,&temp,TRUE))
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
}
else
{
SetpDOBegin(&temp,1);
SetpDOEnd(&temp,0);
SetpType(&temp,MULTIFIELD);
SetpValue(&temp,ProceduralPrimitiveData(theEnv)->NoParamValue);
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
}
if (EvaluationData(theEnv)->EvaluationError)
return(FALSE);
slot->override = TRUE;
slot_exp = slot_exp->nextArg->nextArg;
}
return(TRUE);
}
/*****************************************************************************
NAME : EvaluateClassDefaults
DESCRIPTION : Evaluates default slots only - slots that were specified
by overrides (sp->override == 1) are ignored)
INPUTS : 1) Instance address
RETURNS : Nothing useful
SIDE EFFECTS : Each DATA_OBJECT slot in the instance's slot array is replaced
by the evaluation (by EvaluateExpression) of the expression
in the slot list. The old expression-values
are deleted.
NOTES : None
*****************************************************************************/
static void EvaluateClassDefaults(
void *theEnv,
INSTANCE_TYPE *ins)
{
INSTANCE_SLOT *slot;
DATA_OBJECT temp,junk;
register unsigned i;
if (ins->initializeInProgress == 0)
{
PrintErrorID(theEnv,"INSMNGR",15,FALSE);
SetEvaluationError(theEnv,TRUE);
EnvPrintRouter(theEnv,WERROR,"init-slots not valid in this context.\n");
return;
}
for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
{
slot = ins->slotAddresses[i];
/* ===========================================================
Slot-overrides are just a short-hand for put-slots, so they
should be done with messages. Defaults are from the class
definition and can be placed directly.
=========================================================== */
if (!slot->override)
{
if (slot->desc->dynamicDefault)
{
if (EvaluateAndStoreInDataObject(theEnv,(int) slot->desc->multiple,
(EXPRESSION *) slot->desc->defaultValue,
&temp,TRUE))
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function init-slots");
}
else if (((slot->desc->shared == 0) || (slot->desc->sharedCount == 1)) &&
(slot->desc->noDefault == 0))
DirectPutSlotValue(theEnv,ins,slot,(DATA_OBJECT *) slot->desc->defaultValue,&junk);
else if (slot->valueRequired)
{
PrintErrorID(theEnv,"INSMNGR",14,FALSE);
EnvPrintRouter(theEnv,WERROR,"Override required for slot ");
EnvPrintRouter(theEnv,WERROR,ValueToString(slot->desc->slotName->name));
EnvPrintRouter(theEnv,WERROR," in instance ");
EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name));
EnvPrintRouter(theEnv,WERROR,".\n");
SetEvaluationError(theEnv,TRUE);
}
slot->valueRequired = FALSE;
if (ins->garbage == 1)
{
EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name));
EnvPrintRouter(theEnv,WERROR," instance deleted by slot-override evaluation.\n");
SetEvaluationError(theEnv,TRUE);
}
if (EvaluationData(theEnv)->EvaluationError)
return;
}
slot->override = FALSE;
}
ins->initSlotsCalled = 1;
}
#if DEBUGGING_FUNCTIONS
/***************************************************
NAME : PrintInstanceWatch
DESCRIPTION : Prints out a trace message for the
creation/deletion of an instance
INPUTS : 1) The trace string indicating if
this is a creation or deletion
2) The instance
RETURNS : Nothing usful
SIDE EFFECTS : Watch message printed
NOTES : None
***************************************************/
static void PrintInstanceWatch(
void *theEnv,
char *traceString,
INSTANCE_TYPE *theInstance)
{
EnvPrintRouter(theEnv,WTRACE,traceString);
EnvPrintRouter(theEnv,WTRACE," instance ");
PrintInstanceNameAndClass(theEnv,WTRACE,theInstance,TRUE);
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -