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
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403