KodeCreator.cc
Go to the documentation of this file.00001 #include "Kodu/Parsing/Parser.h"
00002 #include "Kodu/Primitives/KoduCondition.h"
00003 #include "Kodu/Primitives/KoduAction.h"
00004
00005 namespace Kodu {
00006
00007 bool Parser::KodeCreator::createKode(const std::vector<ParsedPage*>& tempPages,
00008 std::vector<KoduPage*>& koduPages)
00009 {
00010
00011 const std::size_t kTempPagesSize = tempPages.size();
00012 for (std::size_t pgIndex = 0; pgIndex < kTempPagesSize; pgIndex++) {
00013
00014 ParsedPage* tempPage = NULL;
00015
00016
00017 bool currentPageRequiresVision = false;
00018
00019
00020 PARSER_ASSERT(((tempPage = tempPages[pgIndex]) != NULL),
00021 errorMessage << "Temp page[" << pgIndex << "] is NULL!");
00022
00023
00024 KoduPage* koduPage = NULL;
00025
00026
00027 PARSER_ASSERT(((koduPage = new KoduPage(tempPage->getPageNumber())) != NULL),
00028 errorMessage << "An error occurred while trying to create a new Kodu page\n");
00029
00030
00031
00032 const std::size_t kRuleCount = tempPage->getRuleCount();
00033 for (std::size_t rIndex = 0; rIndex < kRuleCount; rIndex++) {
00034 ParsedRule* tempRule = NULL;
00035 KoduAction* koduAction = NULL;
00036 KoduCondition* koduCondition = NULL;
00037
00038
00039 PARSER_ASSERT(((tempRule = tempPage->getRuleInPos(rIndex)) != NULL),
00040 errorMessage << "Temp page[" << pgIndex << "], Temp Rule[" << rIndex
00041 << "] is NULL!");
00042
00043 int ruleNumber = tempRule->getRuleNumber();
00044 int parentNumber = tempRule->getParentNumber();
00045
00046
00047
00048 PARSER_ASSERT(((koduCondition = getConditionKode(tempRule->getConditionPhrase())) != NULL),
00049 errorMessage << "An error occurred while trying to create the condition for "
00050 << "rule " << ruleNumber << ". See above.");
00051
00052
00053
00054 PARSER_ASSERT(((koduAction = getActionKode(tempRule->getActionPhrase())) != NULL),
00055 errorMessage << "An error occurred while trying to create the action for "
00056 << "rule " << ruleNumber << ". See above.");
00057
00058
00059 KoduRule* koduRule = NULL;
00060
00061
00062 PARSER_ASSERT(((koduRule = new KoduRule(ruleNumber, parentNumber)) != NULL),
00063 errorMessage << "An error occurred while trying to create a Kodu rule.");
00064
00065 koduRule->condition = koduCondition;
00066 koduRule->action = koduAction;
00067
00068
00069
00070
00071 koduPage->addKoduRule(koduRule);
00072
00073
00074
00075
00076 if (currentPageRequiresVision == false) {
00077
00078 if ((koduRule->condition->getConditionType() == KoduCondition::CT_SEE)
00079
00080 || (koduRule->condition->getConditionType() == KoduCondition::CT_BUMP)
00081
00082 || (koduRule->action->getActionType() == KoduAction::AT_MOTION
00083 && static_cast<KoduActionMotion*>(koduRule->action)->motionTypeIsMove())
00084
00085 || (koduRule->action->getActionType() == KoduAction::AT_GRAB))
00086 {
00087
00088 currentPageRequiresVision = true;
00089 koduPage->setPageRequiresVision(true);
00090 }
00091 }
00092
00093
00094 tempRule = NULL;
00095 koduAction = NULL;
00096 koduCondition = NULL;
00097 koduRule = NULL;
00098 }
00099
00100 koduPages.push_back(koduPage);
00101
00102
00103
00104 tempPage = NULL;
00105 koduPage = NULL;
00106 }
00107 return true;
00108 }
00109
00110 KoduCondition* Parser::KodeCreator::getConditionKode(ParsedPhrase* tempCondition) {
00111
00112 PARSER_ASSERT((tempCondition != NULL),
00113 errorMessage << "The variable that (temporarily) holds the parsed action is NULL!");
00114
00115
00116 std::string conditionStr = tempCondition->getPhraseHead()->getKeywordData();
00117
00118
00119 KoduCondition* condition = NULL;
00120
00121
00122 if (conditionStr == "always") {
00123 PARSER_ASSERT(((condition = new KoduConditionAlways()) != NULL),
00124 errorMessage << "An error occurred while trying to create the Kodu Condition Always.\n");
00125
00126 std::cout << "Created Always condition...\n";
00127 return condition;
00128 }
00129
00130
00131 std::vector<TokenBase*> tempModifiers = tempCondition->getPhraseModifiers();
00132
00133
00134 if (conditionStr == "bump") {
00135
00136 PARSER_ASSERT(((condition = createBumpKode(tempModifiers)) != NULL),
00137 errorMessage << "An error occurred while trying to create the Bump condition. "
00138 << "See above.");
00139 std::cout << "Created Bump condition...\n";
00140 }
00141
00142
00143 else if (conditionStr == "got") {
00144
00145 PARSER_ASSERT(((condition = createGotKode(tempModifiers)) != NULL),
00146 errorMessage << "An error occurred while trying to create the Got condition. "
00147 << "See above.");
00148 std::cout << "Created Got condition...\n";
00149 }
00150
00151
00152 else if (conditionStr == "see") {
00153
00154 PARSER_ASSERT(((condition = createSeeKode(tempModifiers)) != NULL),
00155 errorMessage << "An error occurred while trying to create the See condition. "
00156 << "See above.");
00157
00158 }
00159 else if (conditionStr == "hear") {
00160 PARSER_ASSERT(((condition = createHearKode(tempModifiers)) != NULL),
00161 errorMessage << "An error occurred while trying to create the Hear condition. "
00162 << "See above.");
00163 std::cout << "Created Hear condition...\n";
00164 }
00165
00166
00167 else if (conditionStr == "scored") {
00168
00169 PARSER_ASSERT(((condition = createScoredKode(tempModifiers)) != NULL),
00170 errorMessage << "An error occurred while trying to create the Scored condition. "
00171 << "See above.");
00172 std::cout << "Created Scored condition...\n";
00173 }
00174
00175 else if (conditionStr == "timer") {
00176
00177 PARSER_ASSERT(((condition = createTimerKode(tempModifiers)) != NULL),
00178 errorMessage << "An error occurred while trying to create the Timer condition. See above.");
00179 std::cout << "Created Timer condition...\n";
00180 } else if (conditionStr == "gamepad") {
00181 PARSER_ASSERT(((condition = createGamepadKode(tempModifiers)) != NULL),
00182 errorMessage << "An error occured creating joystick event");
00183 std::cout << "Created Gamepad condition...\n";
00184 }
00185
00186 else {
00187 PARSER_ASSERT((ERROR),
00188 errorMessage << "The keyword \"" << conditionStr
00189 << "\" is not a recognized condition.");
00190
00191 }
00192 return condition;
00193 }
00194
00195 KoduAction* Parser::KodeCreator::getActionKode(ParsedPhrase* tempAction) {
00196
00197 PARSER_ASSERT((tempAction != NULL),
00198 errorMessage << "The variable that (temporarily) hold the parsed action is NULL!");
00199
00200
00201 std::string actionStr = tempAction->getPhraseHead()->getKeywordData();
00202
00203
00204 KoduAction* action = NULL;
00205
00206
00207 if (actionStr == "do_nothing") {
00208 PARSER_ASSERT(((action = new KoduActionDoNothing()) != NULL),
00209 errorMessage << "An error occurred while trying to create the Do Nothing action.");
00210 std::cout << "Created Do Nothing action...\n";
00211
00212 return action;
00213 }
00214
00215
00216 std::vector<TokenBase*> tempModifiers = tempAction->getPhraseModifiers();
00217
00218 if (actionStr == "give"){
00219 PARSER_ASSERT(((action = createGiveKode(tempModifiers)) != NULL),
00220 errorMessage << "An error occurred while trying to create the Give action. "
00221 << "See above.");
00222 std::cout << "Created Give Action...\n";
00223
00224 }
00225
00226 else if (actionStr == "drop") {
00227
00228 PARSER_ASSERT(((action = createDropKode(tempModifiers)) != NULL),
00229 errorMessage << "An error occurred while trying to create the Drop action. "
00230 << "See above.");
00231 std::cout << "Created Drop action...\n";
00232 }
00233
00234 else if (actionStr == "grab") {
00235
00236 PARSER_ASSERT(((action = createGrabKode(tempModifiers)) != NULL),
00237 errorMessage << "An error occurred while trying to create the Grab action. "
00238 << "See above.");
00239 std::cout << "Created Grab action...\n";
00240 }
00241
00242 else if (actionStr == "move") {
00243
00244 PARSER_ASSERT(((action = createMoveKode(tempModifiers)) != NULL),
00245 errorMessage << "An error occurred while trying to create the Move (Motion) action. "
00246 << "See above.");
00247
00248 }
00249
00250 else if (actionStr == "play") {
00251
00252 PARSER_ASSERT(((action = createPlayKode(tempModifiers)) != NULL),
00253 errorMessage << "An error occurred while trying to create the Play action. "
00254 << "See above.");
00255 std::cout << "Created Play action...\n";
00256 }
00257
00258 else if (actionStr == "say") {
00259
00260 PARSER_ASSERT(((action = createSayKode(tempModifiers)) != NULL),
00261 errorMessage << "An error occurred while trying to create the Say action. "
00262 << "See above.");
00263 std::cout << "Created Say action...\n";
00264 }
00265
00266 else if (actionStr == "score" || actionStr == "set_score" || actionStr == "subtract") {
00267
00268 PARSER_ASSERT(((action = createScoreKode(actionStr, tempModifiers)) != NULL),
00269 errorMessage << "An error occurred while trying to create the "
00270 << "Score/Set Score/Subtract action. See above.");
00271 std::cout << "Created Scoring (score | set score | subtract) action...\n";
00272 }
00273
00274 else if (actionStr == "switch_to_page") {
00275 int pageNumb = static_cast<int>(tempAction->getPhraseModifiers()[0]->getNumericData());
00276 PARSER_ASSERT(((action = new KoduActionPageSwitch(NumericGenerator(pageNumb, 0))) != NULL),
00277 errorMessage << "An error occurred while trying to create the Page Switch action.");
00278 std::cout << "Created Page Switch action...\n";
00279 }
00280
00281 else if (actionStr == "turn") {
00282
00283 PARSER_ASSERT(((action = createTurnKode(tempModifiers)) != NULL),
00284 errorMessage << "An error occurred while trying to create the Turn (Motion) action. "
00285 << "See above.");
00286 std::cout << "Created Turn (Motion) action...\n";
00287 }
00288
00289 else {
00290
00291 PARSER_ASSERT((ERROR),
00292 errorMessage << "The keyword \"" << actionStr << "\" is not a recognized action.");
00293 }
00294 return action;
00295 }
00296
00297 bool Parser::KodeCreator::isComparisonOperator(TokenBase* mod) {
00298 return (mod != NULL && mod->isKeywordToken()
00299 && Parser::isValidComparisonOperator(mod->getKeywordData()));
00300 }
00301
00302 bool Parser::KodeCreator::isScoreDesignator(TokenBase* mod) {
00303 return (mod != NULL && mod->isKeywordToken()
00304 && (Parser::isValidColor(mod->getKeywordData())
00305 || Parser::isValidScoreLetter(mod->getKeywordData())));
00306 }
00307
00308 bool Parser::KodeCreator::isNumericSpecifier(TokenBase* mod) {
00309 return (mod != NULL
00310 && (mod->isNumericToken() || (mod->isKeywordToken() && mod->getKeywordData() == "random")));
00311 }
00312
00313 bool Parser::KodeCreator::numericGenParser(std::vector<TokenBase*>& mods, NumericGenerator& numgen) {
00314 float constOrModuloDivisor = -1.0f;
00315 float moduloDivisor = -1.0f;
00316 bool prevTokenWasNumeric = false;
00317 bool randomKeywordFound = false;
00318 bool randomTokenWasFoundBeforeNumericToken = false;
00319
00320
00321 while (!mods.empty() && (mods[0]->isNumericToken() || mods[0]->isKeywordToken())) {
00322
00323 if (mods[0]->isNumericToken()) {
00324
00325 PARSER_ASSERT((!prevTokenWasNumeric),
00326 errorMessage << "A numeric token cannot succeed another numeric token. "
00327 "Token \"" << mods[0]->getNumericData() << "\" caused the error.");
00328
00329 if (constOrModuloDivisor < 0.0f) {
00330
00331 constOrModuloDivisor = mods[0]->getNumericData();
00332
00333 prevTokenWasNumeric = true;
00334 } else if (moduloDivisor < 0.0f) {
00335
00336 moduloDivisor = mods[0]->getNumericData();
00337 prevTokenWasNumeric = true;
00338 }
00339 }
00340
00341 else {
00342 if (mods[0]->getKeywordData() == "random") {
00343
00344 PARSER_ASSERT((!randomKeywordFound),
00345 errorMessage << "Only one random modifier is allowed in an action or a condition.");
00346
00347 randomKeywordFound = true;
00348
00349 prevTokenWasNumeric = false;
00350
00351 if (constOrModuloDivisor < 0.0f) {
00352 randomTokenWasFoundBeforeNumericToken = true;
00353 }
00354 } else {
00355
00356
00357 break;
00358 }
00359 }
00360
00361 GeneralFncs::destroyPtrInVector(mods, 0);
00362 }
00363
00364
00365 if (randomKeywordFound) {
00366
00367 if (moduloDivisor >= 0.0f) {
00368 numgen.setNumericValues(constOrModuloDivisor, moduloDivisor);
00369 }
00370
00371 else if (constOrModuloDivisor >= 0.0f) {
00372
00373 if (randomTokenWasFoundBeforeNumericToken) {
00374 numgen.setNumericValues(0.0f, constOrModuloDivisor);
00375 }
00376
00377 else {
00378 numgen.setNumericValues(constOrModuloDivisor, 5.0f);
00379 }
00380 }
00381
00382 else {
00383 numgen.setNumericValues(0.0f, 5.0f);
00384 }
00385 }
00386
00387 else {
00388 numgen.setNumericValues(constOrModuloDivisor, 0.0f);
00389 }
00390 return true;
00391 }
00392 }