Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Tools/Xabsl2/Xabsl2Engine/Xabsl2Engine.cpp

Go to the documentation of this file.

    00001 /**
    00002 * @file Xabsl2Engine.cpp
    00003 *
    00004 * Implementation of class Xabsl2Engine
    00005 *
    00006 * @author Matthias Jüngel
    00007 * @author Martin Lötzsch
    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   // the total number of options in the intermediate code
    00090   int numberOfOptions = (int)input.readValue();
    00091
    00092   // create empty options
    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   // create the options and its states
    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   // create the agents
    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   // check for loops in the option graph
    00122   for (i=0;i<agents.getSize();i++)
    00123   {
    00124     Xabsl2Option* currentOptionPath[1000];
    00125
    00126     currentOptionPath[0] = agents[i]->getRootOption();
    00127
    00128     // call recursively the checkForLoops function
    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         // check for the subsequent option of each state whether the referenced
    00158         // option is contained in the current option path
    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       // recursion
    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   // check if the option exists
    00211   if (!options.exists(name)) return false;
    00212
    00213   // set the curren root option to the requested option
    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