00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Xabsl2Engine.h"
00011
00012 Xabsl2Engine::Xabsl2Engine(Xabsl2ErrorHandler& e,unsigned long (*pTimeFunction)())
00013 : Xabsl2Symbols(e), selectedAgent(0), rootOption(0),
00014 selectedBasicBehavior(0), errorHandler(e), initialized(false),
00015 pTimeFunction(pTimeFunction)
00016 {
00017 }
00018
00019 Xabsl2Engine::~Xabsl2Engine()
00020 {
00021 int i;
00022 for (i=0; i< options.getSize(); i++)
00023 if (options[i]!=0)
00024 delete options[i];
00025 for (i=0; i< agents.getSize(); i++)
00026 if (agents[i]!=0)
00027 delete agents[i];
00028 }
00029
00030 void Xabsl2Engine::execute()
00031 {
00032 Xabsl2Option* currentOption = rootOption;
00033
00034 int i;
00035
00036 while (currentOption!=0)
00037 {
00038 currentOption->execute();
00039
00040 Xabsl2Option* nextOption = currentOption->activeState->subsequentOption;
00041 if (nextOption == 0)
00042 {
00043 selectedBasicBehavior = currentOption->activeState->subsequentBasicBehavior;
00044 }
00045 currentOption = nextOption;
00046 }
00047
00048 for (i=0; i< options.getSize(); i++)
00049 {
00050 Xabsl2Option* option = options[i];
00051 option->optionWasActive = option->optionIsActive;
00052 option->optionIsActive = false;
00053 }
00054
00055 setOutputSymbols();
00056
00057 executeSelectedBasicBehavior();
00058 }
00059
00060 void Xabsl2Engine::executeSelectedBasicBehavior()
00061 {
00062
00063 selectedBasicBehavior->execute();
00064
00065 for (int i=0;i<basicBehaviors.getSize();i++)
00066 {
00067 basicBehaviors[i].basicBehaviorWasActiveDuringLastExecutionOfEngine = false;
00068 }
00069
00070 selectedBasicBehavior->basicBehaviorWasActiveDuringLastExecutionOfEngine = true;
00071 }
00072
00073 void Xabsl2Engine::createOptionGraph(Xabsl2InputSource& input)
00074 {
00075 int i;
00076 char buf1[100],buf2[100];
00077
00078 if (initialized)
00079 {
00080 errorHandler.error("createOptionGraph(): Don't call this function twice");
00081 return;
00082 }
00083 if (!input.open())
00084 {
00085 errorHandler.error("createOptionGraph(): Can't open input source");
00086 return;
00087 }
00088
00089
00090 int numberOfOptions = (int)input.readValue();
00091
00092
00093 for (i=0; i< numberOfOptions; i++)
00094 {
00095 input.readString(buf1,99);
00096 options.append(buf1,new Xabsl2Option(buf1,input,errorHandler,pTimeFunction));
00097 }
00098 XABSL2_DEBUG_INIT(errorHandler.message("registered %i options",numberOfOptions));
00099
00100
00101 for (i=0; i< numberOfOptions; i++)
00102 {
00103 XABSL2_DEBUG_INIT(errorHandler.message("creating option \"%s\"",options[i]->n));
00104 options[i]->create(input,options,basicBehaviors,*this);
00105 if (errorHandler.errorsOccurred)
00106 {
00107 errorHandler.error("Xabsl2Engine::createOptionGraph(): could not create option \"%s\"",options[i]->n);
00108 return;
00109 }
00110 }
00111
00112
00113 int numberOfAgents = (int)input.readValue();
00114 for (i=0; i< numberOfAgents; i++)
00115 {
00116 input.readString(buf1,99);
00117 input.readString(buf2,99);
00118 agents.append(buf1,new Xabsl2Agent(buf1,options.getElement(buf2),errorHandler));
00119 }
00120
00121
00122 for (i=0;i<agents.getSize();i++)
00123 {
00124 Xabsl2Option* currentOptionPath[1000];
00125
00126 currentOptionPath[0] = agents[i]->getRootOption();
00127
00128
00129 if (checkForLoops(currentOptionPath,0))
00130 {
00131 errorHandler.error("createOptionGraph(): The created option graph contains loops");
00132 };
00133 }
00134
00135
00136 selectedAgent = agents[0];
00137 selectedBasicBehavior = &basicBehaviors[0];
00138 rootOption = selectedAgent->getRootOption();
00139
00140 XABSL2_DEBUG_INIT(errorHandler.message("selected agent: \"%s\"",selectedAgent->n));
00141 input.close();
00142 initialized = true;
00143 }
00144
00145
00146 bool Xabsl2Engine::checkForLoops(Xabsl2Option* currentOptionPath[],int currentDepth)
00147 {
00148 int i,j;
00149 Xabsl2Option* currentOption = currentOptionPath[currentDepth];
00150
00151 for (i=0; i<currentOption->states.getSize(); i++)
00152 {
00153 if (currentOption->states[i]->subsequentOption != 0)
00154 {
00155 for(j=0; j<=currentDepth; j++)
00156 {
00157
00158
00159 if (currentOption->states[i]->subsequentOption == currentOptionPath[j])
00160 {
00161 errorHandler.error("checkForLoops() : state \"%s\" in option \"%s\" references subsequent option \"%s\". But option \"%s\" is also directly or indirectly referenced by option \"%s\".",
00162 currentOption->states[i]->n,
00163 currentOption->n,
00164 currentOption->states[i]->subsequentOption->n,
00165 currentOption->n,
00166 currentOption->states[i]->subsequentOption->n);
00167
00168 return true;
00169 }
00170 }
00171
00172
00173 currentOptionPath[currentDepth+1] = currentOption->states[i]->subsequentOption;
00174 if (checkForLoops(currentOptionPath,currentDepth+1))
00175 {
00176 return true;
00177 }
00178 }
00179 }
00180
00181 return false;
00182 }
00183
00184
00185 void Xabsl2Engine::registerBasicBehavior(Xabsl2BasicBehavior& basicBehavior)
00186 {
00187 XABSL2_DEBUG_INIT(errorHandler.message("registering basic behavior \"%s\"",basicBehavior.n));
00188
00189 if (basicBehaviors.exists(basicBehavior.n))
00190 {
00191 errorHandler.error("registerBasicBehavior(): basic behavior \"%s\" was already registered",basicBehavior.n);
00192 return;
00193 }
00194 basicBehaviors.append(basicBehavior.n,basicBehavior);
00195 }
00196
00197 bool Xabsl2Engine::setSelectedBasicBehavior(const char* name)
00198 {
00199 if (!basicBehaviors.exists(name))
00200 return false;
00201 else
00202 {
00203 selectedBasicBehavior = &basicBehaviors.getElement(name);
00204 return true;
00205 }
00206 }
00207
00208 bool Xabsl2Engine::setRootOption(const char* name)
00209 {
00210
00211 if (!options.exists(name)) return false;
00212
00213
00214 rootOption = options.getElement(name);
00215
00216 return true;
00217 }
00218
00219 void Xabsl2Engine::setRootOption()
00220 {
00221 rootOption = selectedAgent->getRootOption();
00222 }
00223
00224 const Xabsl2Option* Xabsl2Engine::getRootOption() const
00225 {
00226 return rootOption;
00227 }
00228
00229 bool Xabsl2Engine::setBasicBehaviorParameter(const char* name, const char* param, double value)
00230 {
00231 if (!basicBehaviors.exists(name))
00232 {
00233 return false;
00234 }
00235 else if (!basicBehaviors.getElement(name).parameters.exists(param))
00236 {
00237 return false;
00238 }
00239 else
00240 {
00241 basicBehaviors.getElement(name).parameters.setElement(param,value);
00242 return false;
00243 }
00244 }
00245
00246 bool Xabsl2Engine::setOptionParameter(const char* name, const char* param, double value)
00247 {
00248 if (!options.exists(name))
00249 {
00250 return false;
00251 }
00252 else if (!options.getElement(name)->parameters.exists(param))
00253 {
00254 return false;
00255 }
00256 else
00257 {
00258 options.getElement(name)->parameters.setElement(param,value);
00259 return false;
00260 }
00261 }
00262
00263 const char* Xabsl2Engine::getSelectedAgentName()
00264 {
00265 return selectedAgent->n;
00266 }
00267
00268 const Xabsl2BasicBehavior* Xabsl2Engine::getSelectedBasicBehavior()
00269 {
00270 return selectedBasicBehavior;
00271 }
00272
00273 bool Xabsl2Engine::setSelectedAgent(const char* name)
00274 {
00275 if (!agents.exists(name))
00276 {
00277 return false;
00278 }
00279
00280 Xabsl2Agent* newAgent = agents.getElement(name);
00281
00282 if (selectedAgent != newAgent)
00283 {
00284 selectedAgent = newAgent;
00285 rootOption = selectedAgent->getRootOption();
00286 }
00287
00288 return true;
00289 }
00290