CValue* CIfExpr::Calculate() /* pre: ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE a new object containing the value of m_e2 if m_guard is a boolean FALSE an new errorvalue if m_guard is not a boolean */ { CValue *guardval; guardval = m_guard->Calculate(); const STR_String& text = guardval->GetText(); guardval->Release(); if (&text == &CBoolValue::sTrueString) { return m_e1->Calculate(); } else if (&text == &CBoolValue::sFalseString) { return m_e2->Calculate(); } else { return new CErrorValue("Guard should be of boolean type"); } }
SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr, SCA_IObject* gameobj, const STR_String& propname, const STR_String& propval, const STR_String& propmaxval, KX_PROPSENSOR_TYPE checktype) : SCA_ISensor(gameobj,eventmgr), m_checktype(checktype), m_checkpropval(propval), m_checkpropmaxval(propmaxval), m_checkpropname(propname), m_range_expr(NULL) { //CParser pars; //pars.SetContext(this->AddRef()); //CValue* resultval = m_rightexpr->Calculate(); CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { m_previoustext = orgprop->GetText(); } orgprop->Release(); if (m_checktype==KX_PROPSENSOR_INTERVAL) { PrecalculateRangeExpression(); } Init(); }
void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) { bool expressionresult = false; if (!m_exprCache) { CParser parser; parser.SetContext(this->AddRef()); m_exprCache = parser.ProcessText(m_exprText); } if (m_exprCache) { CValue* value = m_exprCache->Calculate(); if (value) { if (value->IsError()) { printf("%s\n", value->GetText().ReadPtr()); } else { float num = (float)value->GetNumber(); expressionresult = !MT_fuzzyZero(num); } value->Release(); } } for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { SCA_IActuator* actua = *i; logicmgr->AddActiveActuator(actua,expressionresult); } }
void SCA_KeyboardSensor::LogKeystrokes() { CValue *tprop = GetParent()->GetProperty(m_targetprop); SCA_IInputDevice *inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice(); std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; const std::wstring typedtext = inputdev->GetText(); std::wstring proptext = converter.from_bytes(tprop->GetText()); /* Convert all typed key in the prop string, if the key are del or * backspace we remove the last string item. */ for (std::wstring::const_iterator it = typedtext.begin(), end = typedtext.end(); it != end; ++it) { const wchar_t item = *it; if (item == '\b' || item == 127) { if (proptext.size()) { proptext.resize(proptext.size() - 1); } } else if (item == '\r') { // Do nothing } else { proptext.push_back(item); } } CStringValue *newstringprop = new CStringValue(converter.to_bytes(proptext), m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); }
// // Get text description of property with name <inName>, returns an empty string if there is no property named <inName> // const STR_String& CValue::GetPropertyText(const STR_String & inName) { const static STR_String sEmpty(""); CValue *property = GetProperty(inName); if (property) return property->GetText(); else return sEmpty; }
void SCA_KeyboardSensor::AddToTargetProp(int keyIndex) { if (IsPrintable(keyIndex)) { CValue* tprop = GetParent()->GetProperty(m_targetprop); if (tprop) { /* overwrite the old property */ if (IsDelete(keyIndex)) { /* strip one char, if possible */ STR_String newprop = tprop->GetText(); int oldlength = newprop.Length(); if (oldlength >= 1 ) { int newlength=oldlength; BLI_str_cursor_step_prev_utf8(newprop, newprop.Length(), &newlength); newprop.SetLength(newlength); CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); } } else { /* append */ char pchar = ToCharacter(keyIndex, IsShifted()); STR_String newprop = tprop->GetText() + pchar; CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); } } else { if (!IsDelete(keyIndex)) { /* Make a new property. Deletes can be ignored. */ char pchar = ToCharacter(keyIndex, IsShifted()); STR_String newprop = pchar; CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); } } } }
void SCA_KeyboardSensor::AddToTargetProp(int keyIndex, int unicode) { if (IsPrintable(keyIndex)) { CValue* tprop = GetParent()->GetProperty(m_targetprop); if (IsDelete(keyIndex)) { /* Make a new property. Deletes can be ignored. */ if (tprop) { /* overwrite the old property */ /* strip one char, if possible */ STR_String newprop = tprop->GetText(); int oldlength = newprop.Length(); if (oldlength >= 1 ) { int newlength=oldlength; BLI_str_cursor_step_prev_utf8(newprop, newprop.Length(), &newlength); newprop.SetLength(newlength); CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); } } } else { char utf8_buf[7]; size_t utf8_len; utf8_len = BLI_str_utf8_from_unicode(unicode, utf8_buf); utf8_buf[utf8_len] = '\0'; STR_String newprop = tprop ? (tprop->GetText() + utf8_buf) : utf8_buf; CStringValue * newstringprop = new CStringValue(newprop, m_targetprop); GetParent()->SetProperty(m_targetprop, newstringprop); newstringprop->Release(); } } }
bool CListValue::CheckEqual(CValue* first,CValue* second) { bool result = false; CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second); if (eqval==NULL) return false; const STR_String& text = eqval->GetText(); if (&text==&CBoolValue::sTrueString) { result = true; } eqval->Release(); return result; }
/** * pre: * ret: a new object containing the value of m_e1 if m_guard is a boolean true * a new object containing the value of m_e2 if m_guard is a boolean false * an new errorvalue if m_guard is not a boolean */ CValue* CIfExpr::Calculate() { CValue *guardval; guardval = m_guard->Calculate(); const std::string& text = guardval->GetText(); guardval->Release(); if (text == CBoolValue::sTrueString) { return m_e1->Calculate(); } else if (text == CBoolValue::sFalseString) { return m_e2->Calculate(); } else { return new CErrorValue("Guard should be of boolean type"); } }
void KX_KetsjiEngine::RenderDebugProperties() { STR_String debugtxt; int xcoord = 10; // mmmm, these constants were taken from blender source int ycoord = 14; // to 'mimic' behaviour float tottime = m_logger->GetAverage(); if (tottime < 1e-6f) { tottime = 1e-6f; } // Set viewport to entire canvas RAS_Rect viewport; m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight())); /* Framerate display */ if (m_show_framerate) { debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord, ycoord, m_canvas->GetWidth() /* RdV, TODO ?? */, m_canvas->GetHeight() /* RdV, TODO ?? */); ycoord += 14; } /* Profile and framerate display */ if (m_show_profile) { for (int j = tc_first; j < tc_numCategories; j++) { debugtxt.Format(m_profileLabels[j]); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord,ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); double time = m_logger->GetAverage((KX_TimeCategory)j); debugtxt.Format("%.3fms (%2.2f %%)", time*1000.f, time/tottime * 100.f); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord + 60 ,ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); ycoord += 14; } } /* Property display*/ if (m_show_debug_properties && m_propertiesPresent) { KX_SceneList::iterator sceneit; for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) { KX_Scene* scene = *sceneit; /* the 'normal' debug props */ vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties(); for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin(); !(it==debugproplist.end());it++) { CValue* propobj = (*it)->m_obj; STR_String objname = propobj->GetName(); STR_String propname = (*it)->m_name; if (propname == "__state__") { // reserve name for object state KX_GameObject* gameobj = static_cast<KX_GameObject*>(propobj); unsigned int state = gameobj->GetState(); debugtxt = objname + "." + propname + " = "; bool first = true; for (int statenum=1;state;state >>= 1, statenum++) { if (state & 1) { if (!first) { debugtxt += ","; } debugtxt += STR_String(statenum); first = false; } } m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord, ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); ycoord += 14; } else { CValue* propval = propobj->GetProperty(propname); if (propval) { STR_String text = propval->GetText(); debugtxt = objname + "." + propname + " = " + text; m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord, ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); ycoord += 14; } } }
bool SCA_PropertySensor::CheckPropertyCondition() { m_recentresult=false; bool result=false; bool reverse = false; switch (m_checktype) { case KX_PROPSENSOR_NOTEQUAL: reverse = true; case KX_PROPSENSOR_EQUAL: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { const STR_String& testprop = orgprop->GetText(); // Force strings to upper case, to avoid confusion in // bool tests. It's stupid the prop's identity is lost // on the way here... if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) { m_checkpropval.Upper(); } result = (testprop == m_checkpropval); /* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000" * this could be made into a generic Value class function for comparing values with a string. */ if (result==false && dynamic_cast<CFloatValue *>(orgprop) != NULL) { float f; if (EOF == sscanf(m_checkpropval.ReadPtr(), "%f", &f)) { //error } else { result = (f == ((CFloatValue *)orgprop)->GetFloat()); } } /* end patch */ } orgprop->Release(); if (reverse) result = !result; break; } case KX_PROPSENSOR_EXPRESSION: { /* if (m_rightexpr) { CValue* resultval = m_rightexpr->Calculate(); if (resultval->IsError()) { int i=0; STR_String errortest = resultval->GetText(); printf(errortest); } else { result = resultval->GetNumber() != 0; } } */ break; } case KX_PROPSENSOR_INTERVAL: { //CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); //if (orgprop) //{ if (m_range_expr) { CValue* vallie = m_range_expr->Calculate(); if (vallie) { const STR_String& errtext = vallie->GetText(); if (&errtext == &CBoolValue::sTrueString) { result = true; } else { if (vallie->IsError()) { //printf (errtext.ReadPtr()); } } vallie->Release(); } } //} //cout << " \nSens:Prop:interval!"; /* need implementation here!!! */ break; } case KX_PROPSENSOR_CHANGED: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { if (m_previoustext != orgprop->GetText()) { m_previoustext = orgprop->GetText(); result = true; } } orgprop->Release(); //cout << " \nSens:Prop:changed!"; /* need implementation here!!! */ break; } default: ; /* error */ } //the concept of Edge and Level triggering has unwanted effect for KX_PROPSENSOR_CHANGED //see Game Engine bugtracker [ #3809 ] if (m_checktype != KX_PROPSENSOR_CHANGED) { m_recentresult=result; } else { m_recentresult=result;//true; } return result; }
bool SCA_PropertySensor::CheckPropertyCondition() { m_recentresult=false; bool result=false; bool reverse = false; switch (m_checktype) { case KX_PROPSENSOR_NOTEQUAL: reverse = true; /* fall-through */ case KX_PROPSENSOR_EQUAL: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { const std::string& testprop = orgprop->GetText(); // Force strings to upper case, to avoid confusion in // bool tests. It's stupid the prop's identity is lost // on the way here... if ((testprop == CBoolValue::sTrueString) || (testprop == CBoolValue::sFalseString)) { boost::to_upper(m_checkpropval); } result = (testprop == m_checkpropval); /* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000" * this could be made into a generic Value class function for comparing values with a string. */ if (result==false && (orgprop->GetValueType() == VALUE_FLOAT_TYPE)) { float f = std::stof(m_checkpropval); result = (f == ((CFloatValue *)orgprop)->GetFloat()); } /* end patch */ } orgprop->Release(); if (reverse) result = !result; break; } case KX_PROPSENSOR_EXPRESSION: { break; } case KX_PROPSENSOR_INTERVAL: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { const float min = std::stof(m_checkpropval); const float max = std::stof(m_checkpropmaxval); float val; if (orgprop->GetValueType() == VALUE_STRING_TYPE) { val = std::stof(orgprop->GetText()); } else { val = orgprop->GetNumber(); } result = (min <= val) && (val <= max); } orgprop->Release(); break; } case KX_PROPSENSOR_CHANGED: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { if (m_previoustext != orgprop->GetText()) { m_previoustext = orgprop->GetText(); result = true; } } orgprop->Release(); break; } case KX_PROPSENSOR_LESSTHAN: reverse = true; /* fall-through */ case KX_PROPSENSOR_GREATERTHAN: { CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { const float ref = std::stof(m_checkpropval); float val; if (orgprop->GetValueType() == VALUE_STRING_TYPE) { val = std::stof(orgprop->GetText()); } else { val = orgprop->GetNumber(); } if (reverse) { result = val < ref; } else { result = val > ref; } } orgprop->Release(); break; } default: ; /* error */ } //the concept of Edge and Level triggering has unwanted effect for KX_PROPSENSOR_CHANGED //see Game Engine bugtracker [ #3809 ] m_recentresult = result; return result; }
CExpression *CParser::Ex(int i) { // parses an expression in the input, starting at priority i, and // returns an CExpression, containing the parsed input CExpression *e1 = NULL, *e2 = NULL; int opkind2; if (i < NUM_PRIORITY) { e1 = Ex(i + 1); while ((sym == opsym) && (Priority(opkind) == i)) { opkind2 = opkind; NextSym(); e2 = Ex(i + 1); switch (opkind2) { case OPmodulus: e1 = new COperator2Expr(VALUE_MOD_OPERATOR,e1, e2); break; case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break; case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break; case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break; case OPdivide: e1 = new COperator2Expr(VALUE_DIV_OPERATOR,e1, e2); break; case OPand: e1 = new COperator2Expr(VALUE_AND_OPERATOR,e1, e2); break; case OPor: e1 = new COperator2Expr(VALUE_OR_OPERATOR,e1, e2); break; case OPequal: e1 = new COperator2Expr(VALUE_EQL_OPERATOR,e1, e2); break; case OPunequal: e1 = new COperator2Expr(VALUE_NEQ_OPERATOR,e1, e2); break; case OPgreater: e1 = new COperator2Expr(VALUE_GRE_OPERATOR,e1, e2); break; case OPless: e1 = new COperator2Expr(VALUE_LES_OPERATOR,e1, e2); break; case OPgreaterequal: e1 = new COperator2Expr(VALUE_GEQ_OPERATOR,e1, e2); break; case OPlessequal: e1 = new COperator2Expr(VALUE_LEQ_OPERATOR,e1, e2); break; default: MT_assert(false); break; // should not happen } } } else if (i == NUM_PRIORITY) { if ((sym == opsym) && ( (opkind == OPminus) || (opkind == OPnot) || (opkind == OPplus) ) ) { NextSym(); switch (opkind) { /* +1 is also a valid number! */ case OPplus: e1 = new COperator1Expr(VALUE_POS_OPERATOR, Ex(NUM_PRIORITY)); break; case OPminus: e1 = new COperator1Expr(VALUE_NEG_OPERATOR, Ex(NUM_PRIORITY)); break; case OPnot: e1 = new COperator1Expr(VALUE_NOT_OPERATOR, Ex(NUM_PRIORITY)); break; default: { // should not happen e1 = Error("operator +, - or ! expected"); } } } else { switch (sym) { case constsym: { switch (constkind) { case booltype: e1 = new CConstExpr(new CBoolValue(boolvalue)); break; case inttype: { cInt temp; temp = strtoll(const_as_string, NULL, 10); /* atoi is for int only */ e1 = new CConstExpr(new CIntValue(temp)); break; } case floattype: { double temp; temp = atof(const_as_string); e1 = new CConstExpr(new CFloatValue(temp)); break; } case stringtype: e1 = new CConstExpr(new CStringValue(const_as_string,"")); break; default : MT_assert(false); break; } NextSym(); break; } case lbracksym: NextSym(); e1 = Ex(1); Term(rbracksym); break; case ifsym: { CExpression *e3; NextSym(); Term(lbracksym); e1 = Ex(1); Term(commasym); e2 = Ex(1); if (sym == commasym) { NextSym(); e3 = Ex(1); } else { e3 = new CConstExpr(new CEmptyValue()); } Term(rbracksym); e1 = new CIfExpr(e1, e2, e3); break; } case idsym: { e1 = new CIdentifierExpr(const_as_string,m_identifierContext); NextSym(); break; } case errorsym: { MT_assert(!e1); STR_String errtext="[no info]"; if (errmsg) { CValue* errmsgval = errmsg->Calculate(); errtext=errmsgval->GetText(); errmsgval->Release(); //e1 = Error(errmsg->Calculate()->GetText());//new CConstExpr(errmsg->Calculate()); if ( !(errmsg->Release()) ) { errmsg=NULL; } else { // does this happen ? MT_assert("does this happen"); } } e1 = Error(errtext); break; } default: NextSym(); //return Error("Expression expected"); MT_assert(!e1); e1 = Error("Expression expected"); } } } return e1; }