/* ASCEND modelling environment
Copyright (C) 2007 Carnegie Mellon University
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*//** @file
The following functions give an automatic, default form for the
'default_all' and 'default_self' methods usually written as explicit
METHODs in a model. EXPERIMENTAL.
*//*
by John Pye, 15 Feb 2007.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#define DEFAULT_DEBUG
#ifdef DEFAULT_DEBUG
# include
# include
#endif
/*------------------------------------------------------------------------------
visit child atoms of the current model (don't visit sub models) and set
to ATOM default values
*/
static int defaultself_visit_childatoms1(struct Instance *inst);
int defaultself_visit_childatoms(struct Instance *root, struct gl_list_t *arglist, void *userdata){
/* arglist is a list of gllist of instances */
if (arglist == NULL ||
gl_length(arglist) == 0L ||
gl_length((struct gl_list_t *)gl_fetch(arglist,1)) != 1 ||
gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),1) == NULL) {
return defaultself_visit_childatoms1(root);
}else{
return defaultself_visit_childatoms1(
(struct Instance *)gl_fetch( (struct gl_list_t *)gl_fetch(arglist,1),1 )
);
}
}
/**
Find atom children in the present model and set them to their ATOM DEFAULT
values.
*/
static
int defaultself_visit_childatoms1(struct Instance *inst){
int i,n;
struct Instance *c;
struct TypeDescription *type;
/* default any child atoms' values */
n = NumberChildren(inst);
for(i = 1; i <= n; ++i){
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("Child %d...", i);
#endif
c = InstanceChild(inst,i);
if(c==NULL)continue;
type = InstanceTypeDesc(c);
if(BaseTypeIsAtomic(type)){
if(!AtomDefaulted(type))continue;
switch(GetBaseType(type)){
case real_type:
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("Setting to atom default = %f",GetRealDefault(type));
#endif
SetRealAtomValue(c, GetRealDefault(type), 0);
break;
case integer_type: SetIntegerAtomValue(c, GetIntDefault(type), 0); break;
case boolean_type: SetBooleanAtomValue(c, GetBoolDefault(type), 0); break;
case symbol_type: SetSymbolAtomValue(c, GetSymDefault(type)); break;
case set_type: /* what is the mechanism for defaulting of sets? */
default: ASC_PANIC("invalid type");
}
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("Reset atom to default value");
#endif
}else if(GetBaseType(type)==array_type){
/* descend into arrays */
defaultself_visit_childatoms1(c);
}
}
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("defaultself_visit_childatoms1 returning %d",0);
#endif
return 0;
}
/*------------------------------------------------------------------------------
visit submodels, running 'default_self' on each
*/
struct DefaultAll_data{
symchar *method_name;
};
static int defaultself_visit_submodels1(struct Instance *inst
, struct DefaultAll_data *data
);
int defaultself_visit_submodels(struct Instance *root
, struct gl_list_t *arglist, void *userdata
){
struct DefaultAll_data data;
data.method_name = AddSymbol("default_self");
#ifdef DEFAULT_DEBUG
char *name1 = WriteInstanceNameString(root,NULL);
CONSOLE_DEBUG("Running on '%s'",name1);
ASC_FREE(name1);
#endif
/* arglist is a list of gllist of instances */
if (arglist == NULL ||
gl_length(arglist) == 0L ||
gl_length((struct gl_list_t *)gl_fetch(arglist,1)) != 1 ||
gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),1) == NULL) {
return defaultself_visit_submodels1(root,&data);
}else{
return defaultself_visit_submodels1(
(struct Instance *)gl_fetch( (struct gl_list_t *)gl_fetch(arglist,1),1 )
, &data
);
}
}
/**
Find child models in the present model and run their 'default_self' methods
*/
static
int defaultself_visit_submodels1(struct Instance *inst
, struct DefaultAll_data *data
){
int i, n, err = 0;
struct Instance *c;
struct TypeDescription *type;
struct InitProcedure *method;
enum Proc_enum pe;
type = InstanceTypeDesc(inst);
/* loop through child atoms */
n = NumberChildren(inst);
for(i = 1; i <= n; ++i){
c = InstanceChild(inst,i);
if(c==NULL)continue;
type = InstanceTypeDesc(c);
if(model_type == GetBaseType(type)){
/* run 'default_all' for all child models */
method = FindMethod(type,data->method_name);
if(method){
#ifdef DEFAULT_DEBUG
char *name1 = WriteInstanceNameString(c,NULL);
CONSOLE_DEBUG("Running METHOD %s on '%s'",SCP(data->method_name),name1);
ASC_FREE(name1);
#endif
pe = Initialize(c , CreateIdName(ProcName(method))
, SCP(data->method_name)
,ASCERR
,0, NULL, NULL
);
if(pe!=Proc_all_ok)err += 1;
}else{
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("Recursing into array...");
#endif
ERROR_REPORTER_HERE(ASC_PROG_ERR,"No '%s' found for type '%s'",SCP(data->method_name),SCP(GetName(type)));
return 1;
}
}else if(array_type == GetBaseType(type)){
if(defaultself_visit_submodels1(c,data))err += 1;
}
}
#ifdef DEFAULT_DEBUG
CONSOLE_DEBUG("defaultself_visit_submodels1 returning %d",err);
#endif
return err;
}
#if 0
/**
NOTE YET IMPLEMENTED: we need to be able to pass string constants to
methods, which I don't think is possible yet.
*/
int Asc_VisitSubmodels(struct Instance *root
, struct gl_list_t *arglist, void *userdata
){
struct DefaultAll_data data;
(void)userdata;
ERROR_REPORTER_HERE(ASC_USER_ERROR,"not implemented");
return 1;
if (arglist == NULL
|| gl_length(arglist) == 0L
|| gl_length((struct gl_list_t *)gl_fetch(arglist,1)) != 2
|| gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),1) == NULL
|| gl_fetch((struct gl_list_t *)gl_fetch(arglist,1),2) == NULL
){
ERROR_REPORTER_HERE(ASC_USER_ERROR,"EXTERNAL visit_submodels(SELF,'methodname') called with bad argument list");
return 1;
}
data.method_name = AddSymbol("default_all");
return Asc_DefaultAll1(
(struct Instance *)gl_fetch( (struct gl_list_t *)gl_fetch(arglist,1),1 )
, &data
);
}
#endif