ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo)); String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo); ExpressionResult nameres = m_Name->Evaluate(frame); CHECK_RESULT(nameres); Value name = nameres.GetValue(); if (!name.IsString()) BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo)); ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(Type::GetByName(type), name); if (!item) BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo)); Dictionary::Ptr scope = item->GetScope(); if (scope) scope->CopyTo(frame.Locals); ExpressionResult result = item->GetExpression()->Evaluate(frame, dhint); CHECK_RESULT(result); return Empty; }
std::list<Index*> IndexPage::find(BufferManager* manager, FilterParser* parser) { if (!isLoaded()) { loadPage(manager); } std::list<Index*> result; for (int x = 0; x < size; x++) { BSONObj* key = elements[x]->key; if (key->getString("_id").compare("c597-43e1-ae9b-6f5451b28295") == 0) { cout << "Hey!" << endl; } bool match = false; ExpressionResult* expresult = parser->eval(*key); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { result.push_back(elements[x]); } } for (int x = 0; x <= size; x++) { IndexPage* innerPage = pointers[x]; if (innerPage != NULL) { std::list<Index*> inner = innerPage->find(manager, parser); result.insert(result.begin(), inner.begin(), inner.end()); } } return result; }
ExpressionResult DictExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { Value self; if (!m_Inline) { self = frame.Self; frame.Self = new Dictionary(); } Value result; try { for (Expression *aexpr : m_Expressions) { ExpressionResult element = aexpr->Evaluate(frame, m_Inline ? dhint : NULL); CHECK_RESULT(element); result = element.GetValue(); } } catch (...) { if (!m_Inline) std::swap(self, frame.Self); throw; } if (m_Inline) return result; else { std::swap(self, frame.Self); return self; } }
ExpressionResult LogicalNegateExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { ExpressionResult operand = m_Operand->Evaluate(frame); CHECK_RESULT(operand); return !operand.GetValue().ToBool(); }
ExpressionResult NegateExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { ExpressionResult operand = m_Operand->Evaluate(frame); CHECK_RESULT(operand); return ~(long)operand.GetValue(); }
ExpressionResult ThrowExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { ExpressionResult messageres = m_Message->Evaluate(frame); CHECK_RESULT(messageres); Value message = messageres.GetValue(); BOOST_THROW_EXCEPTION(ScriptError(message, m_DebugInfo, m_IncompleteExpr)); }
BSONObj* DBController::findFirst(const char* db, const char* ns, const char* select, const char* filter, const BSONObj* options) throw(ParseException) { if (_logger->isDebug()) _logger->debug(2, "DBController::findFirst db: %s, ns: %s, select: %s, filter: %s", db, ns, select, filter); std::string filedir = _dataDir + db; filedir = filedir + FILESEPARATOR; std::stringstream ss; ss << filedir << ns << ".dat"; std::string filename = ss.str(); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); MMapInputStream* mmis = new MMapInputStream(filename.c_str(), 0); DBFileInputStream* dbStream = new DBFileInputStream(mmis); BSONArrayObj result; BSONInputStream* bis = new BSONInputStream(mmis); FilterParser* parser = FilterParser::parse(filter); BSONBufferedObj* obj = NULL; BSONObj* bsonResult = NULL; mmis->seek(29); while (!mmis->eof()) { if (obj == NULL) { obj = new BSONBufferedObj(mmis->pointer(), mmis->length() - mmis->currentPos()); } else { obj->reset(mmis->pointer(), mmis->length() - mmis->currentPos()); } mmis->seek(mmis->currentPos() + obj->bufferLength()); // Only "active" Records if (obj->getInt("_status") == 1) { ExpressionResult* result = parser->eval(*obj); if (result->type() == ExpressionResult::RT_BOOLEAN) { bool bres = *result; if (bres) { bsonResult = obj->select(select); break; } } delete result; } if (bsonResult) { break; } } if (obj != NULL) delete obj; dbStream->close(); delete dbStream; mmis->close(); delete mmis; delete parser; delete bis; return bsonResult; }
ExpressionResult ForExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("For loops are not allowed in sandbox mode.", m_DebugInfo)); ExpressionResult valueres = m_Value->Evaluate(frame, dhint); CHECK_RESULT(valueres); return VMOps::For(frame, m_FKVar, m_FVVar, valueres.GetValue(), m_Expression, m_DebugInfo); }
ExpressionResult ApplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Apply rules are not allowed in sandbox mode.", m_DebugInfo)); ExpressionResult nameres = m_Name->Evaluate(frame); CHECK_RESULT(nameres); return VMOps::NewApply(frame, m_Type, m_Target, nameres.GetValue(), m_Filter, m_Package, m_FKVar, m_FVVar, m_FTerm, m_ClosedVars, m_IgnoreOnError, m_Expression, m_DebugInfo); }
ExpressionResult* evalEqual(const BSONObj& bson, BaseExpression* left, BaseExpression* right) { ExpressionResult* valLeft = left->eval(bson); ExpressionResult* valRight= right->eval(bson); bool result = false; if (valLeft->type() != valRight->type()) { result = false; } else if (((valLeft->type() != ExpressionResult::RT_NULL) && (valRight->type() == ExpressionResult::RT_NULL)) || ((valLeft->type() == ExpressionResult::RT_NULL) && (valRight->type() != ExpressionResult::RT_NULL))) { result = false; } else { // the types are ensured to be equal switch (valLeft->type()) { case ExpressionResult::RT_INT: result = ((__int32)*valLeft == (__int32)*valRight); break; case ExpressionResult::RT_LONG: case ExpressionResult::RT_LONG64: result = ((__int64)*valLeft == (__int64)*valRight); break; case ExpressionResult::RT_DOUBLE: result = ((double)*valLeft == (double)*valRight); break; case ExpressionResult::RT_BOOLEAN: result = ((bool)*valLeft == (bool)*valRight); break; case ExpressionResult::RT_PTRCHAR: { result = ((djondb::string)*valLeft == (djondb::string)*valRight); break; } break; case ExpressionResult::RT_STRINGDB: { std::string leftS = *valLeft; std::string rightS = *valRight; result = (leftS.compare(rightS) == 0); } break; case ExpressionResult::RT_BSON: { BSONObj* bleft = (BSONObj*)*valLeft; BSONObj* bright = (BSONObj*)*valRight; result = (*bleft == *bright); break; } } } delete valLeft; delete valRight; return new ExpressionResult(result); }
ExpressionResult* not_expression(BaseExpression* expression, const BSONObj& bson) { ExpressionResult* tmpresult = expression->eval(bson); ExpressionResult* result = NULL; if (tmpresult->type() == ExpressionResult::RT_BOOLEAN) { bool bres = *tmpresult; result = new ExpressionResult(!bres); } else { throw ParseException(D_ERROR_PARSEERROR, "Exists signature is wrong. Use Exists($'field')."); } delete tmpresult; return result; }
ExpressionResult LibraryExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Loading libraries is not allowed in sandbox mode.", m_DebugInfo)); ExpressionResult libres = m_Operand->Evaluate(frame, dhint); CHECK_RESULT(libres); Loader::LoadExtensionLibrary(libres.GetValue()); return Empty; }
ExpressionResult ConditionalExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { ExpressionResult condition = m_Condition->Evaluate(frame, dhint); CHECK_RESULT(condition); if (condition.GetValue().ToBool()) return m_TrueBranch->Evaluate(frame, dhint); else if (m_FalseBranch) return m_FalseBranch->Evaluate(frame, dhint); return Empty; }
ExpressionResult* evalComparison(const BSONObj& bson, const FILTER_OPERATORS& oper, BaseExpression* left, BaseExpression* right) { ExpressionResult* valLeft = left->eval(bson); ExpressionResult* valRight= right->eval(bson); if (valLeft->type() != valRight->type()) { // ERROR types does not match delete valLeft; delete valRight; return new ExpressionResult(false); } bool resultGreather = false; // this will compare only greather than, and at the end will invert // based on the sign if ((valLeft->type() != ExpressionResult::RT_NULL) && (valRight->type() == ExpressionResult::RT_NULL)) { resultGreather = true; } else if (((valLeft->type() == ExpressionResult::RT_NULL) && (valRight->type() != ExpressionResult::RT_NULL))) { resultGreather = false; } else { switch (valLeft->type()) { case ExpressionResult::RT_INT: resultGreather = ((__int32)*valLeft > (__int32)*valRight); break; case ExpressionResult::RT_LONG: case ExpressionResult::RT_LONG64: resultGreather = ((__int64)*valLeft > (__int64)*valRight); break; case ExpressionResult::RT_DOUBLE: resultGreather = ((double)*valLeft > (double)*valRight); break; } } ExpressionResult* result = NULL; if ((!resultGreather && (oper == FO_GREATEREQUALTHAN)) || (resultGreather && (oper == FO_LESSEQUALTHAN))) { result = evalEqual(bson, left, right); } else { bool bres; if ((oper == FO_LESSTHAN) || (oper == FO_LESSEQUALTHAN)) { bres = !resultGreather; }else { bres = resultGreather; } result = new ExpressionResult(bres); } delete valLeft; delete valRight; return result; }
ExpressionResult ArrayExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { Array::Ptr result = new Array(); result->Reserve(m_Expressions.size()); for (Expression *aexpr : m_Expressions) { ExpressionResult element = aexpr->Evaluate(frame); CHECK_RESULT(element); result->Add(element.GetValue()); } return result; }
void setResultForContribution( const fvMesh &mesh, ExpressionResult &result, const scalarField &values ) { result.setResult(values); }
ExpressionResult UsingExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Using directives are not allowed in sandbox mode.", m_DebugInfo)); ExpressionResult importres = m_Name->Evaluate(frame); CHECK_RESULT(importres); Value import = importres.GetValue(); if (!import.IsObjectType<Dictionary>()) BOOST_THROW_EXCEPTION(ScriptError("The parameter must resolve to an object of type 'Dictionary'", m_DebugInfo)); ScriptFrame::AddImport(import); return Empty; }
void setResultForContribution<FieldValuePluginFunction>( const fvMesh &mesh, ExpressionResult &result, const scalarField &values ) { autoPtr<volScalarField> pResult( new volScalarField( IOobject( "contributionFrom_", // +Driver::driverName(), mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("contribution",dimless,0) ) ); #ifdef FOAM_NO_DIMENSIONEDINTERNAL_IN_GEOMETRIC const_cast<scalarField&>(pResult->internalField().field()) #else pResult->internalField() #endif =values; pResult->correctBoundaryConditions(); result.setObjectResult(pResult); }
ExpressionResult WhileExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("While loops are not allowed in sandbox mode.", m_DebugInfo)); for (;;) { ExpressionResult condition = m_Condition->Evaluate(frame, dhint); CHECK_RESULT(condition); if (!condition.GetValue().ToBool()) break; ExpressionResult loop_body = m_LoopBody->Evaluate(frame, dhint); CHECK_RESULT_LOOP(loop_body); } return Empty; }
ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Object definitions are not allowed in sandbox mode.", m_DebugInfo)); ExpressionResult typeres = m_Type->Evaluate(frame, dhint); CHECK_RESULT(typeres); Type::Ptr type = typeres.GetValue(); String name; if (m_Name) { ExpressionResult nameres = m_Name->Evaluate(frame, dhint); CHECK_RESULT(nameres); name = nameres.GetValue(); } return VMOps::NewObject(frame, m_Abstract, type, name, m_Filter, m_Zone, m_Package, m_DefaultTmpl, m_IgnoreOnError, m_ClosedVars, m_Expression, m_DebugInfo); }
void StackExpressionResult::push(ExpressionResult &atEnd) { if(debug) { Info << "StackExpressionResult::push(ExpressionResult &atEnd)" << endl; Info << "Pushing: " << atEnd << endl; } if(!hasValue()) { // this is the first push // static_cast<ExpressionResult>(*this)=atEnd; ExpressionResult::operator=(atEnd); } else { if(valueType()!=atEnd.valueType()) { FatalErrorIn("StackExpressionResult::push(const ExpressionResult &atEnd)") << "Type of pushed value " << atEnd.valueType() << " is not the expected type " << valueType() << endl << abort(FatalError); } if(valueType()==pTraits<scalar>::typeName) { pushInternal<scalar>(atEnd); } else if(valueType()==pTraits<vector>::typeName) { pushInternal<vector>(atEnd); } else if(valueType()==pTraits<tensor>::typeName) { pushInternal<tensor>(atEnd); } else if(valueType()==pTraits<symmTensor>::typeName) { pushInternal<symmTensor>(atEnd); } else if(valueType()==pTraits<sphericalTensor>::typeName) { pushInternal<sphericalTensor>(atEnd); } else { FatalErrorIn("StackExpressionResult::push(const ExpressionResult &atEnd)") << " Unsopported value type " << valueType() << endl << abort(FatalError); } } if(debug) { Info << "After push: " << *this << endl; } }
std::list<Index*> IndexPage::find(FilterParser* parser) const { std::list<Index*> result; for (int x = 0; x < size; x++) { BSONObj* key = elements[x]->key; bool match = false; ExpressionResult* expresult = parser->eval(*key); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { result.push_back(elements[x]); } } for (int x = 0; x <= size; x++) { IndexPage* innerPage = pointers[x]; if (innerPage != NULL) { std::list<Index*> inner = innerPage->find(parser); result.insert(result.begin(), inner.begin(), inner.end()); } } return result; }
void StackExpressionResult::operator=(const ExpressionResult& rhs) { if(debug) { Info << "StackExpressionResult::operator=(const ExpressionResult& rhs)" << endl; } ExpressionResult last( rhs.getUniform( 1, false // issue a warning if the other result is not really uniform ) ); this->push( last ); }
ExpressionResult FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { Value self, vfunc; String index; if (m_FName->GetReference(frame, false, &self, &index)) vfunc = VMOps::GetField(self, index, frame.Sandboxed, m_DebugInfo); else { ExpressionResult vfuncres = m_FName->Evaluate(frame); CHECK_RESULT(vfuncres); vfunc = vfuncres.GetValue(); } if (vfunc.IsObjectType<Type>()) { std::vector<Value> arguments; for (Expression *arg : m_Args) { ExpressionResult argres = arg->Evaluate(frame); CHECK_RESULT(argres); arguments.push_back(argres.GetValue()); } return VMOps::ConstructorCall(vfunc, arguments, m_DebugInfo); } if (!vfunc.IsObjectType<Function>()) BOOST_THROW_EXCEPTION(ScriptError("Argument is not a callable object.", m_DebugInfo)); Function::Ptr func = vfunc; if (!func->IsSideEffectFree() && frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Function is not marked as safe for sandbox mode.", m_DebugInfo)); std::vector<Value> arguments; for (Expression *arg : m_Args) { ExpressionResult argres = arg->Evaluate(frame); CHECK_RESULT(argres); arguments.push_back(argres.GetValue()); } return VMOps::FunctionCall(frame, self, func, arguments); }
void setResultForContribution<FaFieldValuePluginFunction>( const fvMesh &mesh, ExpressionResult &result, const scalarField &values ) { autoPtr<areaScalarField> pResult( new areaScalarField( IOobject( "contributionFrom_", // +Driver::driverName(), mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), FaCommonValueExpressionDriver::faRegionMesh(mesh), dimensionedScalar("contribution",dimless,0) ) ); pResult->internalField()=values; pResult->correctBoundaryConditions(); result.setObjectResult(pResult); }
ExpressionResult IncludeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Includes are not allowed in sandbox mode.", m_DebugInfo)); Expression *expr; String name, path, pattern; switch (m_Type) { case IncludeRegular: { ExpressionResult pathres = m_Path->Evaluate(frame, dhint); CHECK_RESULT(pathres); path = pathres.GetValue(); } expr = ConfigCompiler::HandleInclude(m_RelativeBase, path, m_SearchIncludes, m_Zone, m_Package, m_DebugInfo); break; case IncludeRecursive: { ExpressionResult pathres = m_Path->Evaluate(frame, dhint); CHECK_RESULT(pathres); path = pathres.GetValue(); } { ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint); CHECK_RESULT(patternres); pattern = patternres.GetValue(); } expr = ConfigCompiler::HandleIncludeRecursive(m_RelativeBase, path, pattern, m_Zone, m_Package, m_DebugInfo); break; case IncludeZones: { ExpressionResult nameres = m_Name->Evaluate(frame, dhint); CHECK_RESULT(nameres); name = nameres.GetValue(); } { ExpressionResult pathres = m_Path->Evaluate(frame, dhint); CHECK_RESULT(pathres); path = pathres.GetValue(); } { ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint); CHECK_RESULT(patternres); pattern = patternres.GetValue(); } expr = ConfigCompiler::HandleIncludeZones(m_RelativeBase, name, path, pattern, m_Package, m_DebugInfo); break; } ExpressionResult res(Empty); try { res = expr->Evaluate(frame, dhint); } catch (const std::exception&) { delete expr; throw; } delete expr; return res; }
BSONArrayObj* DBController::findFullScan(const char* db, const char* ns, const char* select, FilterParser* parser, const BSONObj* options) throw(ParseException) { if (_logger->isDebug()) _logger->debug(2, "DBController::findFullScan with parser db: %s, ns: %s", db, ns); std::string filedir = _dataDir + db; filedir = filedir + FILESEPARATOR; std::stringstream ss; ss << filedir << ns << ".dat"; std::string filename = ss.str(); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, INDEX_FTYPE); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); //FileInputStream* fis = new FileInputStream(filename.c_str(), "rb"); MMapInputStream* mmis = new MMapInputStream(filename.c_str(), 0); DBFileInputStream* dbStream = new DBFileInputStream(mmis); BSONArrayObj* result = new BSONArrayObj(); BSONInputStream* bis = new BSONInputStream(dbStream); std::set<std::string> tokens = parser->xpathTokens(); std::string filterSelect; if ((strcmp(select, "*") != 0) && (tokens.size() > 0)) { // this will reserve enough space to concat the filter tokens filterSelect.reserve(tokens.size() * 100); filterSelect.append("$'_status'"); for (std::set<std::string>::iterator i = tokens.begin(); i != tokens.end(); i++) { std::string token = *i; filterSelect.append(", "); filterSelect.append("$'"); filterSelect.append(token); filterSelect.append("'"); } } else { filterSelect = "*"; } mmis->seek(29); BSONBufferedObj* obj = NULL; __int64 maxResults = 3000; if ((options != NULL) && options->has("limit")) { BSONContent* content = options->getContent("limit"); if (content->type() == INT_TYPE) { maxResults = options->getInt("limit"); } else if (content->type() == LONG_TYPE) { maxResults = options->getLong("limit"); } } else { std::string smax = getSetting("max_results"); if (smax.length() > 0) { #ifdef WINDOWS maxResults = _atoi64(smax.c_str()); #else maxResults = atoll(smax.c_str()); #endif } } __int64 count = 0; while (!mmis->eof() && (count < maxResults)) { if (obj == NULL) { obj = new BSONBufferedObj(mmis->pointer(), mmis->length() - mmis->currentPos()); } else { obj->reset(mmis->pointer(), mmis->length() - mmis->currentPos()); } mmis->seek(mmis->currentPos() + obj->bufferLength()); // Only "active" Records if (obj->getInt("_status") == 1) { bool match = false; ExpressionResult* expresult = parser->eval(*obj); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { BSONObj* objSubselect = obj->select(select); result->add(*objSubselect); delete objSubselect; count++; } } } if (obj != NULL) delete obj; delete bis; dbStream->close(); delete dbStream; return result; }
/// For if- and elsif- statements. void Script::HandleConditional(String line) { // Remove first part until ( int index = line.Find('('); line = line.Part(index); /// Use expressions from the MathLib. First parse for functions to provide their values? Or... Expression exp; List<Variable> allVars = GameVars.GetAllExpressionVariables() + variables; exp.functionEvaluators = functionEvaluators; // Set evaluators. bool parseOK = exp.ParseExpression(line); if (!parseOK) { std::cout<<"\nParse error in expression "<<line; return; } ExpressionResult res = exp.Evaluate(allVars); bool statementTrue = res.GetBool(); /// If statement is true, sign this row as finished. if (statementTrue) { // Set line finished to true so the actual content will be processed. lineFinished = true; // Set if-Processed to true so that no elsif- or else- clause will be handled. ScriptLevel & latest = stack.Last(); latest.evaluatedAtLine = currentLine; } else { // Check stuff. ScriptLevel & sl = stack.Last(); int newRow = -1; int ifStack = 0; // If the statement is not true, find an else or endif block..! for (int i = currentLine+1; i < lines.Size(); ++i) { String l = lines[i]; if (sl.type == ScriptLevel::WHILE_LOOP) { if (l.Contains("endwhile")) { // Jump to next after, as regular stopping on endwhile will reboot the loop newRow = i + 1; stack.RemoveLast(); break; } } if (sl.type == ScriptLevel::IF_CLAUSE) { if (l.Contains("elsif") || l.Contains("else") || l.Contains("endif")) { if (ifStack == 0) { newRow = i; break; } if (l.Contains("endif")) --ifStack; } else if (l.Contains("if")) ++ifStack; } } assert(newRow > 0); // Process it next iteration. currentLine = newRow; lineProcessed = false; lineFinished = false; return; } if (lineFinished == false) assert(false && "Line not finished? Something is missing in the if/else/endif block!"); }
void Script::EvaluateLine(String & line) { /// Default line processed once? lineProcessed = true; line.SetComparisonMode(String::NOT_CASE_SENSITIVE); // "80Gray50Alpha.png" #define DEFAULT_TEXTURE_SOURCE "black50Alpha.png" #define DEFAULT_TEXT_SIZE_RATIO 0.3f /// Some state began, take not of it? if (line.Contains("Wait(")) { WaitScript * wait = new WaitScript(line, this); wait->SetDeleteOnEnd(true); ScriptMan.PlayScript(wait); } else if (line.StartsWith("Key:")) { String keyStr = line.Tokenize(":")[1]; keyStr.RemoveSurroundingWhitespaces(); int keyCode = GetKeyForString(keyStr); assert(keyCode != 0); InputMan.KeyDown(MainWindow(), keyCode, false); InputMan.KeyUp(MainWindow(), keyCode); lineFinished = true; } else if (line.Contains("PlayScript(")) { List<String> tokens = line.Tokenize("(),"); // Source of script within the parenthesis. String source = tokens[1]; bool wait = true; Script * scriptParent = this; if (tokens.Size() >= 3) { wait = tokens[2].ParseBool(); if (!wait) { scriptParent = NULL; this->lineFinished = true; } } Script * script = new Script(source, scriptParent); script->source = source; bool loaded = script->Load(); assert(loaded); ScriptMan.PlayScript(script); } else if (line == "DisableActiveUI") { InputMan.DisableActiveUI(); lineFinished = true; uiDisabled = true; } else if (line == "EnableActiveUI") { InputMan.EnableActiveUI(); lineFinished = true; } else if (line.Contains("PreloadTexturesInDirectory(")) { // Fetch the stuff, do the buff String dir = line.Tokenize("()")[1]; List<String> files; int num = GetFilesInDirectory(dir, files); for (int i = 0; i < files.Size(); ++i) { String path = dir + "/" + files[i]; Texture * tex = TexMan.LoadTexture(path); Graphics.QueueMessage(new GMBufferTexture(tex)); } lineFinished = true; } else if (line.Contains("Begin(")) { String stateBeginning = line.Tokenize("()")[1]; if (stateBeginning == "Cutscene") { BeginCutscene(); } lineFinished = true; } else if (line.Contains("End(")) { String stateEnding = line.Tokenize("()")[1]; if (stateEnding == "Cutscene") { EndCutscene(); } lineFinished = true; } else if (line.Contains("EndScript")) { // End it. scriptState = ENDING; } else if (line.Contains("EnterGameState(")) { String name = line.Tokenize("()")[1]; StateChanger * changer = new StateChanger(line, this); ScriptMan.PlayScript(changer); } else if (line.Contains("FadeTo(") || line.Contains("FadeIn(")) { FadeInEffect * fade = new FadeInEffect(line, this); ScriptMan.PlayScript(fade); } else if (line.Contains("FadeInBackground(")) { FadeInBackground * fade = new FadeInBackground(line, this); ScriptMan.PlayScript(fade); } else if (line.Contains("FadeOutBackground(")) { FadeOutBackground * fade = new FadeOutBackground(line, this); ScriptMan.PlayScript(fade); } else if (line.Contains("FadeOut")) { FadeOutEffect * fade = new FadeOutEffect(line, this); ScriptMan.PlayScript(fade); } else if (line.Contains("FadeText(")) { FadeTextEffect * text = new FadeTextEffect(line, this); ScriptMan.PlayScript(text); lineFinished = true; } else if (line.Contains("PlaySong(")) { // Just play it. String song = line.Tokenize("()")[1]; TrackMan.PlayTrack(song); // Line finished straight away. lineFinished = true; } else if (line.Contains("Dialogue")){ /// If raw string, output it straight away! (should later be queued to some kind of dialogue-manager?) if (line.Contains("\"")){ /// Create dialogue UI and append it to the current UI! String text = line.Tokenize("\"")[1]; std::cout<<"\n"<<text; UIButton * dialogue = new UIButton("Dialogue"); dialogue->exitable = false; dialogue->text = text; dialogue->activationMessage = "PopFromStack(this)&Remove(this)&ContinueEvent("+this->name+")"; dialogue->textureSource = DEFAULT_TEXTURE_SOURCE; dialogue->textSizeRatio = DEFAULT_TEXT_SIZE_RATIO; dialogue->sizeRatioY = 0.3f; dialogue->alignmentY = 0.15f; dialogue->state |= UIState::DIALOGUE; // Flag the dialogue-state flag to signify importance! Graphics.QueueMessage(new GMAddUI(dialogue, "root")); Graphics.QueueMessage(GMPushUI::ToUI("Dialogue", ActiveUI())); } /// If no quotes, load the specified dialogue-file and begin processing that instead, waiting until it is finished.! else { /// Give the npc a dialogue? // assert(false); // Send it tot he state too, to attach to the appropriate thingymajig. Message * message = new Message(line); /// Set this event as message->scriptOrigin = this; MesMan.QueueMessage(message); /// Instant thingies. lineFinished = true; } } else if (line.Contains("Answer")){ /// Go to EndAnswers..! lineFinished = true; for (int i = currentLine; i < lines.Size(); ++i){ String line = lines[i]; if (line.Contains("EndAnswers")){ currentLine = i; lineFinished = true; return; } } assert(false && "No EndAnswers found? No good, jaow ;___;"); } else if (line.Contains("BeginAlternatives") || line.Contains("BeginQuestion")){ /// Create dialogue UI and append it to the current UI! String text = line.Tokenize("\"")[1]; std::cout<<"\n"<<text; UIElement * dialogue = new UIElement(); dialogue->exitable = false; dialogue->name = "AlternativesDialogue"; // dialogue->activationMessage = "Remove(this)&ContinueEvent("+this->name+")"; dialogue->textureSource = DEFAULT_TEXTURE_SOURCE; dialogue->sizeRatioY = 0.3f; dialogue->alignmentY = 0.15f; dialogue->state |= UIState::DIALOGUE; // Flag the dialogue-state flag to signify importance! UILabel * dialogueText = new UILabel(); dialogueText->text = text; dialogueText->textSizeRatio = DEFAULT_TEXT_SIZE_RATIO; dialogueText->sizeRatioX = 0.5f; dialogueText->alignmentX = 0.25f; dialogue->AddChild(dialogueText); UIList * dialogueAnswerList = new UIList(); dialogueAnswerList->sizeRatioX = 0.5f; dialogueAnswerList->alignmentX = 0.75f; dialogue->AddChild(dialogueAnswerList); int answers = 0; List<UIElement*> answerList; // Parse and add answers for (int i = currentLine+1; i < lines.Size(); ++i){ String l = lines[i]; l.SetComparisonMode(String::NOT_CASE_SENSITIVE); List<String> tokens = l.Tokenize(" "); String token1 = tokens[0]; token1.SetComparisonMode(String::NOT_CASE_SENSITIVE); if (token1 == "text"){ l.Remove(token1); dialogueText->text = l; dialogueText->text.RemoveInitialWhitespaces(); dialogueText->text.Remove("\""); dialogueText->text.Remove("\""); } else if (l.Contains("Answer")){ ++answers; UIButton * answerButton = new UIButton(); answerButton->name = token1; l.Remove("Answer"); l.RemoveInitialWhitespaces(); l.Remove("\""); l.Remove("\""); answerButton->textureSource = DEFAULT_TEXTURE_SOURCE; answerButton->text = l; answerButton->sizeRatioY = 0.2f; answerButton->activationMessage = "ActivateDialogueAlternative("+name+","+answerButton->name+")&PopFromStack("+dialogue->name+")&Remove("+dialogue->name+")"; answerList.Add(answerButton); } else if (l.Contains("EndAlternatives")){ // Donelir. o-o break; } else { assert(false && "Bad line! Should only be Answer before EndAlternatives!"); } } assert(answers); float sizeRatioY = 0.95f / answers; for (int i = 0; i < answers; ++i){ UIElement * ans = answerList[i]; // ans->sizeRatioY = sizeRatioY; // Stupid to set the sizeRatioY to be this dynamic, yo. dialogueAnswerList->AddChild(ans); } isInAlternativeDialogue = true; Graphics.QueueMessage(new GMAddUI(dialogue, "root")); Graphics.QueueMessage(GMPushUI::ToUI(dialogue, ActiveUI())); } else if (line.Contains("elsif") || line.Contains("elseif") || line.Contains("else if")) { /// Should be in an if-stack, check if we already evaluated. ScriptLevel sl = stack.Last(); assert(sl.type == ScriptLevel::IF_CLAUSE); /// If already evaluated, jump to endif. if (sl.evaluatedAtLine > 0) { // Jump to endif. JumpToEndif(); return; } /// If not, handle the conditional first. HandleConditional(line); } else if (line.Contains("if(") || line.Contains("if (")) { // Add to stack. stack.AddItem(ScriptLevel(ScriptLevel::IF_CLAUSE, currentLine)); HandleConditional(line); } else if (line.Contains("else")) { // if (ifProcessed) // JumpToEndif(); ScriptLevel sl = stack.Last(); assert(sl.type == ScriptLevel::IF_CLAUSE); if (sl.evaluatedAtLine > 0) { JumpToEndif(); return; } lineFinished = true; return; } else if (line.Contains("endif")) { ScriptLevel sl = stack.Last(); assert(sl.type == ScriptLevel::IF_CLAUSE); stack.RemoveLast(); lineFinished = true; } else if (line.Contains("endwhile")) { // Go to start! ScriptLevel sl = stack.Last(); assert(sl.type == ScriptLevel::WHILE_LOOP); currentLine = sl.evaluatedAtLine; String startLine = lines[currentLine]; HandleConditional(startLine); // lineFinished = true; // Evaluate? // stack.RemoveLast(); } else if (line.Contains("while")) { stack.AddItem(ScriptLevel(ScriptLevel::WHILE_LOOP, currentLine)); HandleConditional(line); } /* else if (line.Contains("CreateInt")){ List<String> tokens = line.Tokenize(" \t"); String varName = tokens[1]; int initialValue = 0; if (tokens.Size() >= 3) initialValue = tokens[2].ParseInt(); if (!GameVars.Get(varName)){ GameVars.CreateInt(varName, initialValue); } lineFinished = true; } /* else if (line.Contains("SetInt ")){ List<String> tokens = line.Tokenize(" \t"); String varName = tokens[1]; int value = tokens[2].ParseInt(); GameVars.SetInt(varName, value); lineFinished = true; }*/ else if (line.Contains("Repeatable")){ /// Flag the event as repeatable. repeatable = true; lineFinished = true; } // Consider just making an else-clause for all remaining events to be processed by the specific game instead? else if ( line.Contains("SpawnEntity") || line.Contains("OnApproach") || line.Contains("OnInteract") || line.Contains("DisableMovement") || line.Contains("EnableMovement") || line.Contains("Zone(") || line.Contains("PlacePlayer(") || line.Contains("TrackPlayer") ) { Message * message = new Message(line); /// Set this event as message->scriptOrigin = this; MesMan.QueueMessage(message); /// Instant thingies. lineFinished = true; } else { /// Try evaluate it as an expression. Expression exp; List<Variable> allVars = GameVars.GetAllExpressionVariables() + variables; exp.functionEvaluators = functionEvaluators; // Set evaluators. bool parseOK = exp.ParseExpression(line); if (line.Contains("SetMovementPattern")) int p = 4;; if (parseOK) { ExpressionResult res = exp.Evaluate(allVars); /// Continue until it returns true! o.o if (res.type != DataType::NO_TYPE) { if (res.GetBool() == true) { lineFinished = true; return; } } } // std::cout<<"\nUndefined event command: "<<line; // std::cout<<"\nPassing it as a custom command to the game states for further processing."; Message * message = new Message(line); /// Set this event as source of it. message->scriptOrigin = this; MesMan.QueueMessage(message); lineFinished = true; // assert(false && "Undefined event command!"); }; }
void InspectorWindow::MessageReceived(BMessage* message) { switch (message->what) { case MSG_THREAD_STATE_CHANGED: { ::Thread* thread; if (message->FindPointer("thread", reinterpret_cast<void**>(&thread)) != B_OK) { break; } BReference< ::Thread> threadReference(thread, true); if (thread->State() == THREAD_STATE_STOPPED) { if (fCurrentBlock != NULL) { _SetCurrentBlock(NULL); _SetToAddress(fCurrentAddress); } } break; } case MSG_INSPECT_ADDRESS: { target_addr_t address = 0; if (message->FindUInt64("address", &address) != B_OK) { if (fAddressInput->TextView()->TextLength() == 0) break; fExpressionInfo->SetTo(fAddressInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fExpressionInfo); } else _SetToAddress(address); break; } case MSG_EXPRESSION_EVALUATED: { BString errorMessage; BReference<ExpressionResult> reference; ExpressionResult* value = NULL; if (message->FindPointer("value", reinterpret_cast<void**>(&value)) == B_OK) { reference.SetTo(value, true); if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { Value* primitive = value->PrimitiveValue(); BVariant variantValue; primitive->ToVariant(variantValue); if (variantValue.Type() == B_STRING_TYPE) { errorMessage.SetTo(variantValue.ToString()); } else { _SetToAddress(variantValue.ToUInt64()); break; } } } else { status_t result = message->FindInt32("result"); errorMessage.SetToFormat("Failed to evaluate expression: %s", strerror(result)); } BAlert* alert = new(std::nothrow) BAlert("Inspect Address", errorMessage.String(), "Close"); if (alert != NULL) alert->Go(); break; } case MSG_NAVIGATE_PREVIOUS_BLOCK: case MSG_NAVIGATE_NEXT_BLOCK: { if (fCurrentBlock != NULL) { target_addr_t address = fCurrentBlock->BaseAddress(); if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK) address -= fCurrentBlock->Size(); else address += fCurrentBlock->Size(); BMessage setMessage(MSG_INSPECT_ADDRESS); setMessage.AddUInt64("address", address); PostMessage(&setMessage); } break; } case MSG_MEMORY_BLOCK_RETRIEVED: { TeamMemoryBlock* block = NULL; status_t result; if (message->FindPointer("block", reinterpret_cast<void **>(&block)) != B_OK || message->FindInt32("result", &result) != B_OK) { break; } if (result == B_OK) { _SetCurrentBlock(block); fPreviousBlockButton->SetEnabled(true); fNextBlockButton->SetEnabled(true); } else { BString errorMessage; errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64 ": %s", block->BaseAddress(), strerror(result)); BAlert* alert = new(std::nothrow) BAlert("Inspect address", errorMessage.String(), "Close"); if (alert == NULL) break; alert->Go(NULL); block->ReleaseReference(); } break; } case MSG_EDIT_CURRENT_BLOCK: { _SetEditMode(true); break; } case MSG_MEMORY_DATA_CHANGED: { if (fCurrentBlock == NULL) break; target_addr_t address; if (message->FindUInt64("address", &address) == B_OK && address >= fCurrentBlock->BaseAddress() && address < fCurrentBlock->BaseAddress() + fCurrentBlock->Size()) { fCurrentBlock->Invalidate(); _SetEditMode(false); fListener->InspectRequested(address, this); } break; } case MSG_COMMIT_MODIFIED_BLOCK: { // TODO: this could conceivably be extended to detect the // individual modified regions and only write those back. // That would require potentially submitting multiple separate // write requests, and thus require tracking all the writes being // waited upon for completion. fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(), fMemoryView->GetEditedData(), fCurrentBlock->Size()); break; } case MSG_REVERT_MODIFIED_BLOCK: { _SetEditMode(false); break; } default: { BWindow::MessageReceived(message); break; } } }